perm filename COMSCH.1[SCH,LSP] blob
sn#815687 filedate 1986-04-25 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00578 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00085 00002 ∂29-Nov-84 1009 RPG Comments on the Preliminary Report (2 pages)
C00095 00003 ∂30-Nov-84 1658 RPG Re: Kent Dybvig's Comments on Scheme
C00102 00004 ∂01-Dec-84 1049 RPG Kent Dybvig's Comments on Scheme
C00107 00005 ∂05-Dec-84 1353 RPG Re: Kent Dybvig's Comments on Scheme
C00111 00006 ∂07-Dec-84 1341 RPG [willc: preliminary report of workshop]
C00146 00007 ∂07-Dec-84 1342 RPG Slashification
C00149 00008 ∂09-Dec-84 1252 RPG MIN/MAX, DO/RETURN
C00151 00009 ∂09-Dec-84 1304 RPG Re: critique of preliminary report
C00173 00010 ∂09-Dec-84 1307 RPG apology to Franz Lisp
C00175 00011 ∂10-Dec-84 1123 RPG Scheme conference report
C00179 00012 ∂10-Dec-84 1137 RPG Scheme conference report
C00183 00013 ∂10-Dec-84 1142 RPG Scheme conference report
C00189 00014 ∂12-Dec-84 1711 RPG Re: Scheme conference report
C00191 00015 ∂12-Dec-84 1847 RPG
C00193 00016 ∂15-Dec-84 2257 RPG Scheme bibliography
C00196 00017 ∂16-Dec-84 2313 RPG continuation terminology
C00199 00018 ∂17-Dec-84 1524 RPG continuation terminology
C00203 00019 ∂18-Dec-84 2009 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Common Lisp order of evaluation
C00205 00020 ∂19-Dec-84 0850 @MIT-MC:rhh@MIT-VAX Re: Common Lisp order of evaluation
C00207 00021 ∂19-Dec-84 0912 @MIT-MC:CPH@MIT-OZ Common Lisp order of evaluation
C00208 00022 ∂23-Dec-84 0901 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa length vs. list-length
C00211 00023 ∂23-Dec-84 2330 @MIT-MC:mw%brandeis.csnet@csnet-relay.arpa list-length
C00213 00024 ∂24-Dec-84 1350 @MIT-MC:mw%brandeis.csnet@csnet-relay.arpa list-length
C00215 00025 ∂28-Dec-84 1428 JAR@MIT-MC list-length
C00216 00026 ∂13-Jan-85 1322 JAR@MIT-MC list-length
C00218 00027 ∂13-Jan-85 1328 KMP@MIT-MC policy to adopt
C00220 00028 ∂13-Jan-85 2117 @MIT-MC:CPH@MIT-OZ Scheme String Operations: the Report
C00259 00029 ∂14-Jan-85 0217 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Re: policy to adopt
C00262 00030 ∂15-Jan-85 1914 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa Re: Scheme String Operations: the Report
C00268 00031 ∂15-Jan-85 2339 @MIT-MC:CPH@MIT-OZ Scheme String Operations: the Report
C00278 00032 ∂24-Jan-85 1227 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa Purpose of a "common" Scheme
C00280 00033 ∂31-Jan-85 0921 @MIT-MC:mw%brandeis.csnet@csnet-relay.arpa Resources for Scheme course
C00283 00034 ∂01-Feb-85 0930 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa quotient, remainder, letrec
C00285 00035 ∂02-Feb-85 1040 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa Scheme String Operations
C00291 00036 ∂03-Feb-85 1055 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Re: Scheme String Operations
C00296 00037 ∂03-Feb-85 1059 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa string->symbol, symbol->string
C00300 00038 ∂04-Feb-85 0221 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Chez Scheme
C00305 00039 ∂05-Feb-85 1002 JAR@MIT-MC string->symbol, symbol->string
C00311 00040 ∂05-Feb-85 1007 JAR@MIT-MC Scheme String Operations
C00313 00041 ∂21-Feb-85 1259 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa Draft delayed to 15 March
C00315 00042 ∂10-Mar-85 1716 @MIT-MC:GJS@MIT-EECS Numbers Committee Report
C00351 00043 ∂11-Mar-85 2110 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa I/O proposal
C00377 00044 ∂12-Mar-85 0940 @MIT-MC:mw%brandeis.csnet@csnet-relay.arpa Re: Numbers Committee Report
C00380 00045 ∂12-Mar-85 0954 @MIT-MC:mw%brandeis.csnet@csnet-relay.arpa Re: I/O proposal
C00383 00046 ∂12-Mar-85 1306 @MIT-MC:GJS@MIT-OZ Re: Numbers Committee Report
C00387 00047 ∂12-Mar-85 1441 @MIT-MC:CPH@MIT-OZ I/O proposal
C00389 00048 ∂12-Mar-85 1552 @MIT-MC:GJS@MIT-OZ Re: I/O proposal
C00391 00049 ∂14-Mar-85 1024 JAR@MIT-MC interaction of LOAD and CURRENT-INPUT-STREAM
C00394 00050 ∂14-Mar-85 1228 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa Re: I/O proposal
C00399 00051 ∂15-Mar-85 0801 @MIT-MC:CPH@MIT-OZ I/O proposal
C00402 00052 ∂16-Mar-85 1017 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Re: I/O proposal
C00408 00053 ∂16-Mar-85 1020 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Re: I/O proposal
C00409 00054 ∂17-Mar-85 0839 @MIT-MC:JINX@MIT-OZ I/O proposal
C00416 00055 ∂17-Mar-85 1027 @MIT-MC:CPH@MIT-OZ I/O proposal
C00420 00056 ∂17-Mar-85 2041 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa assertions are better than types
C00431 00057 ∂17-Mar-85 2054 @MIT-MC:CPH@MIT-OZ assertions are better than types
C00432 00058 ∂17-Mar-85 2248 @MIT-MC:KMP@SCRC-STONY-BROOK assertions are better than types
C00438 00059 ∂18-Mar-85 1045 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Re: I/O proposal
C00441 00060 ∂18-Mar-85 1049 JAR@MIT-MC I/O proposal
C00445 00061 ∂18-Mar-85 1123 @MIT-MC:GJS@MIT-OZ Re: I/O proposal
C00447 00062 ∂18-Mar-85 1159 @MIT-MC:GJS@MIT-OZ Re: assertions are better than types
C00459 00063 ∂18-Mar-85 1210 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa Arithmetic overflow
C00462 00064 ∂18-Mar-85 1545 @MIT-MC:linus!ramsdell@mitre-bedford Pointer-less stack allocated arrays.
C00466 00065 ∂18-Mar-85 2056 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa Re: I/O proposal
C00479 00066 ∂19-Mar-85 0456 @MIT-MC:forwarder@CSNET-SH.ARPA Message a011267 -- long message to scheme@mit-mc
C00481 00067 ∂19-Mar-85 0459 @MIT-MC:forwarder@CSNET-SH.ARPA Message a011267 LONG message - part 1
C00547 00068 ∂19-Mar-85 0505 @MIT-MC:forwarder@CSNET-SH.ARPA Message a011267 LONG message - part 2
C00617 00069 ∂19-Mar-85 0515 @MIT-MC:forwarder@CSNET-SH.ARPA Message a011267 LONG message - part 3
C00661 00070 ∂19-Mar-85 1044 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa Keyboard inputs
C00667 00071 ∂19-Mar-85 1445 @MIT-MC:JINX@MIT-OZ Keyboard inputs
C00674 00072 ∂19-Mar-85 2228 @MIT-MC:CPH@MIT-OZ Revisions to String Proposal
C00684 00073 ∂20-Mar-85 1254 JAR@MIT-MC Ports and streams
C00691 00074 ∂20-Mar-85 1542 @MIT-MC:KMP@SCRC-STONY-BROOK Ports and streams
C00693 00075 ∂21-Mar-85 1448 @MIT-MC:linus!ramsdell@mitre-bedford MAPC and MAPCAR
C00696 00076 ∂21-Mar-85 1449 @MIT-MC:linus!ramsdell@mitre-bedford Re: DRAFT of the Revised Revised Report
C00701 00077 ∂21-Mar-85 1554 @MIT-MC:JINX@MIT-OZ DRAFT of the Revised Revised Report
C00706 00078 ∂22-Mar-85 0951 JAR@MIT-MC (if a b)
C00708 00079 ∂22-Mar-85 1322 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa ASSERT, ports, and NIL
C00712 00080 ∂22-Mar-85 1325 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa Re: Revisions to String Proposal
C00714 00081 ∂22-Mar-85 1344 @MIT-MC:GJS@MIT-OZ Re: ASSERT, ports, and NIL
C00715 00082 ∂22-Mar-85 1353 JAR@MIT-MC NIL
C00720 00083 ∂22-Mar-85 1835 @MIT-MC:HUDAK@YALE.ARPA Re: DRAFT of the Revised Revised Report
C00723 00084 ∂22-Mar-85 2049 @MIT-MC:ANDY@SU-SCORE.ARPA Re: DRAFT of the Revised Revised Report
C00725 00085 ∂24-Mar-85 0007 @MIT-MC:CPH@MIT-OZ
C00727 00086 ∂24-Mar-85 0009 @MIT-MC:CPH@MIT-OZ Revisions to String Proposal
C00729 00087 ∂25-Mar-85 1306 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa Re: NIL
C00732 00088 ∂25-Mar-85 1443 @MIT-MC:linus!ramsdell@mitre-bedford ITERATE
C00733 00089 ∂25-Mar-85 1757 @MIT-MC:HUDAK@YALE.ARPA CAR and CDR again
C00737 00090 ∂25-Mar-85 1852 GJC@MIT-MC NIL, experience with VAX-NIL, or NIL is nothing to worry about.
C00741 00091 ∂26-Mar-85 1439 @MIT-MC:linus!ramsdell@mitre-bedford WHEN
C00742 00092 ∂26-Mar-85 1444 @MIT-MC:linus!ramsdell@mitre-bedford LIST?
C00744 00093 ∂26-Mar-85 1501 @MIT-MC:linus!ramsdell@mitre-bedford function names.
C00746 00094 ∂26-Mar-85 1659 @MIT-MC:KMP@SCRC-STONY-BROOK function names.
C00754 00095 ∂26-Mar-85 1703 @MIT-MC:KMP@SCRC-STONY-BROOK How to let macros work without defining what a macro is...
C00761 00096 ∂26-Mar-85 1802 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa Missing CSNET messages
C00763 00097 ∂26-Mar-85 1839 @MIT-MC:GJS@MIT-OZ car/cdr
C00765 00098 ∂27-Mar-85 0212 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Re: DRAFT of the Revised Revised Report
C00769 00099 ∂27-Mar-85 0638 @MIT-MC:JINX@MIT-OZ function names.
C00771 00100 ∂27-Mar-85 0709 @MIT-MC:JINX@MIT-OZ DRAFT of the Revised Revised Report
C00775 00101 ∂27-Mar-85 0722 @MIT-MC:JINX@MIT-OZ How to let macros work without defining what a macro is...
C00777 00102 ∂27-Mar-85 0727 @MIT-MC:JINX@MIT-OZ LIST? -- LIST
C00779 00103 ∂27-Mar-85 0808 GJC@MIT-MC plea for macros
C00782 00104 ∂27-Mar-85 1123 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa Re: ASSERT, ports, and NIL
C00787 00105 ∂27-Mar-85 1140 @MIT-MC:ADAMS@YALE.ARPA Re: DRAFT of the Revised Revised Report
C00789 00106 ∂27-Mar-85 1143 @MIT-MC:cth%indiana.csnet@csnet-relay.arpa Re: Draft of R.R. Report
C00798 00107 ∂27-Mar-85 1207 @MIT-MC:GJS@MIT-OZ flames!
C00800 00108 ∂27-Mar-85 1242 @MIT-MC:JINX@MIT-OZ ASSERT, ports, and NIL
C00802 00109 ∂27-Mar-85 1245 @MIT-MC:JINX@MIT-OZ Draft of R.R. Report
C00805 00110 ∂27-Mar-85 1644 @MIT-MC:linus!ramsdell@mitre-bedford Scheme names
C00808 00111 ∂27-Mar-85 1726 JAR@MIT-MC NIL, again
C00814 00112 ∂28-Mar-85 0611 @MIT-MC:KMP@SCRC-STONY-BROOK How to let macros work without defining what a macro is...
C00822 00113 ∂28-Mar-85 0717 @MIT-MC:HUDAK@YALE.ARPA IF and WHEN
C00824 00114 ∂28-Mar-85 0753 @MIT-MC:JINX@MIT-OZ IF and WHEN
C00825 00115 ∂28-Mar-85 0803 @MIT-MC:JINX@MIT-OZ syntax-expand
C00827 00116 ∂28-Mar-85 1303 @MIT-MC:HUDAK@YALE.ARPA Re: IF and WHEN
C00829 00117 ∂28-Mar-85 1437 @MIT-MC:linus!ramsdell@mitre-bedford Other names for ITERATE
C00831 00118 ∂28-Mar-85 1511 @MIT-MC:JINX@MIT-OZ Other names for ITERATE
C00833 00119 ∂28-Mar-85 2248 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Re: flames!
C00835 00120 ∂29-Mar-85 0713 @MIT-MC:cth%indiana.csnet@csnet-relay.arpa ITERATE, DEFINE and CELLs
C00839 00121 ∂29-Mar-85 0759 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Re: Other names for ITERATE
C00841 00122 ∂29-Mar-85 0851 @MIT-MC:GJS@MIT-OZ WHEN, UNLESS, RECURSE, et. al.
C00843 00123 ∂29-Mar-85 0949 @MIT-MC:JINX@MIT-OZ ITERATE, DEFINE and CELLs
C00852 00124 ∂29-Mar-85 0957 @MIT-MC:JINX@MIT-OZ WHEN, UNLESS, RECURSE, et. al.
C00853 00125 ∂29-Mar-85 1214 JAR@MIT-MC ITERATE, DEFINE, WHEN, cells, etc.
C00858 00126 ∂29-Mar-85 1238 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa names
C00862 00127 ∂29-Mar-85 1537 @MIT-MC:linus!ramsdell@mitre-bedford REC and LETREC
C00864 00128 ∂29-Mar-85 1540 @MIT-MC:linus!ramsdell@mitre-bedford rationalized names
C00866 00129 ∂29-Mar-85 1545 @MIT-MC:linus!ramsdell@mitre-bedford LIST?
C00868 00130 ∂29-Mar-85 1631 @MIT-MC:mw%brandeis.csnet@csnet-relay.arpa Other names for ITERATE
C00870 00131 ∂29-Mar-85 2135 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa NIL vs ()
C00872 00132 ∂29-Mar-85 2138 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa RE: The revised revised Report
C00878 00133 ∂30-Mar-85 0047 @MIT-MC:CPH@MIT-OZ ITERATE, DEFINE and CELLs
C00881 00134 ∂30-Mar-85 0054 @MIT-MC:CPH@MIT-OZ The revised revised Report
C00883 00135 ∂31-Mar-85 1822 JAR@MIT-MC REC and LETREC
C00885 00136 ∂31-Mar-85 1834 JAR@MIT-MC READ-CHAR-READY?
C00887 00137 ∂31-Mar-85 2042 @MIT-MC:cth%indiana.csnet@csnet-relay.arpa REC and LETREC
C00889 00138 ∂31-Mar-85 2045 @MIT-MC:cth%indiana.csnet@csnet-relay.arpa JINX reply on RECUR, DEFINE, ...
C00896 00139 ∂31-Mar-85 2047 @MIT-MC:cth%indiana.csnet@csnet-relay.arpa CPH reply on DEFINE
C00899 00140 ∂01-Apr-85 2047 JAR@MIT-MC CPH reply on DEFINE
C00902 00141 ∂02-Apr-85 0005 @MIT-MC:CPH@MIT-OZ CPH reply on DEFINE
C00904 00142 ∂09-Apr-85 0637 @MIT-MC:wagle%indiana.csnet@csnet-relay.arpa First Class Environments and Their Extenders
C00912 00143 ∂10-Apr-85 0107 @MIT-MC:CPH@MIT-OZ First Class Environments and Their Extenders
C00914 00144 ∂21-Apr-85 0652 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa if, mapcar, mapc, ...
C00922 00145 ∂21-Apr-85 0654 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa lexical syntax for numbers
C00930 00146 ∂21-Apr-85 1444 @MIT-MC:rhh@MIT-VAX reactions to Will's updates
C00933 00147 ∂21-Apr-85 1923 @MIT-MC:JINX@MIT-OZ lexical syntax for numbers
C00935 00148 ∂21-Apr-85 1927 @MIT-MC:JINX@MIT-OZ reactions to Will's updates
C00937 00149 ∂21-Apr-85 1929 @MIT-MC:CPH@MIT-OZ lexical syntax for numbers
C00939 00150 ∂21-Apr-85 1931 @MIT-MC:CPH@MIT-OZ reactions to Will's updates
C00941 00151 ∂22-Apr-85 1103 JAR@MIT-MC hashing
C00944 00152 ∂22-Apr-85 1117 JAR@MIT-MC hashing
C00948 00153 ∂22-Apr-85 1226 @MIT-MC:wagle%indiana.csnet@csnet-relay.arpa mapcar and mapc
C00950 00154 ∂22-Apr-85 1302 @MIT-MC:rhh@MIT-VAX Re: hashing
C00952 00155 ∂22-Apr-85 1544 @MIT-MC:linus!ramsdell@mitre-bedford Two armed IF is essential.
C00954 00156 ∂22-Apr-85 1547 @MIT-MC:linus!ramsdell@mitre-bedford REC => LABEL
C00955 00157 ∂23-Apr-85 0912 @MIT-MC:wagle%indiana.csnet@csnet-relay.arpa Retraction and Resubmission
C00960 00158 ∂23-Apr-85 1336 JAR@MIT-MC Two armed IF is essential.
C00962 00159 ∂24-Apr-85 1541 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa two-armed if (oops)
C00964 00160 ∂25-Apr-85 0902 @MIT-MC:rhh@MIT-VAX number exponent syntax
C00966 00161 ∂26-Apr-85 0037 JAR@MIT-MC number exponent syntax
C00968 00162 ∂26-Apr-85 0351 @MIT-MC:rhh@MIT-VAX Re: number exponent syntax
C00970 00163 ∂21-Jun-85 1631 @MIT-MC.ARPA:willc%tekchips%tektronix.csnet@csnet-relay.arpa lcm
C00973 00164 ∂21-Jun-85 1723 @MIT-MC.ARPA:ANDY@SU-SUSHI.ARPA Re: lcm
C00975 00165 ∂09-Jul-85 2145 @MIT-MC.ARPA:ALTMAN%ti-csl.csnet@csnet-relay.arpa Scheme Benchmark Programs Sought
C00978 00166 ∂09-Jul-85 2325 @MIT-MC.ARPA:mw%brandeis.csnet@csnet-relay.arpa What cr*p
C00980 00167 ∂11-Jul-85 2016 GJC@MIT-MC.ARPA What cr*p
C00982 00168 ∂19-Jul-85 1756 @MIT-MC.ARPA:linus!ramsdell@mitre-bedford CSI Lisp is not tail recursive
C00985 00169 ∂20-Jul-85 0350 GJC@MIT-MC.ARPA truth in advertisement
C00989 00170 ∂22-Jul-85 1043 @MIT-MC.ARPA:gls@THINK-AQUINAS.ARPA truth in advertisement
C00991 00171 ∂22-Jul-85 1522 GJC@MIT-MC.ARPA truth in advertisement
C00993 00172 ∂24-Jul-85 1622 @MIT-MC.ARPA:linus!ramsdell@mitre-bedford
C00996 00173 ∂24-Jul-85 1929 @MIT-MC.ARPA:OXLEY%ti-csl.csnet@csnet-relay.arpa Scheme Not Tail Recursive!!!????
C00999 00174 ∂24-Jul-85 1944 @MIT-MC.ARPA:willc%tekchips%tektronix.csnet@csnet-relay.arpa Re: Scheme Not Tail Recursive!!!????
C01003 00175 ∂25-Jul-85 0342 @MIT-MC.ARPA:GJS@MIT-OZ Re: Scheme Not Tail Recursive!!!????
C01005 00176 ∂25-Jul-85 1115 JAR@MIT-MC.ARPA Are fluids objects?
C01008 00177 ∂25-Jul-85 1125 @MIT-MC.ARPA:JINX@MIT-OZ Scheme Not Tail Recursive!!!????
C01012 00178 ∂25-Jul-85 1310 @MIT-MC.ARPA:JINX@MIT-OZ previous message
C01013 00179 ∂26-Jul-85 1444 @MIT-MC.ARPA:BARTLEY%ti-csl.csnet@csnet-relay.arpa Re: Scheme Not Tail Recursive!!!????
C01015 00180 ∂26-Jul-85 2251 @MIT-MC.ARPA:BARTLEY%ti-csl.csnet@csnet-relay.arpa Ambiguous number syntax
C01017 00181 ∂27-Jul-85 1715 @MIT-MC.ARPA:GJS@MIT-OZ Re: Ambiguous number syntax
C01020 00182 ∂29-Jul-85 1020 @MIT-MC.ARPA:gls@THINK-AQUINAS.ARPA Re: Ambiguous number syntax
C01025 00183 ∂30-Jul-85 2036 GJC@MIT-MC.ARPA Ambiguous number syntax
C01026 00184 ∂31-Jul-85 1159 @MIT-MC.ARPA:CPH@MIT-OZ identifiers and symbols
C01030 00185 ∂31-Jul-85 1445 JAR@MIT-MC.ARPA identifiers and symbols
C01036 00186 ∂01-Aug-85 0915 @MIT-MC.ARPA:BARTLEY%ti-csl.csnet@csnet-relay.arpa Re: identifiers and symbols
C01040 00187 ∂02-Aug-85 1338 @MIT-MC.ARPA:mw%brandeis.csnet@csnet-relay.arpa Re: identifiers and symbols
C01046 00188 ∂05-Aug-85 1836 @MIT-MC.ARPA:unc!dyb%unc.csnet@csnet-relay.arpa Re: identifiers and symbols
C01053 00189 ∂05-Aug-85 1851 @MIT-MC.ARPA:CPH@MIT-OZ identifiers and symbols
C01057 00190 ∂09-Aug-85 1539 JAR@MIT-MC.ARPA Altering quoted structure
C01060 00191 ∂09-Aug-85 1546 JAR@MIT-MC.ARPA (EQV? #\? #\?) ?
C01061 00192 ∂09-Aug-85 1549 JAR@MIT-MC.ARPA Altering quoted structure, addendum
C01063 00193 ∂09-Aug-85 1618 @MIT-MC.ARPA:JINX@MIT-OZ (EQV? #\? #\?) ?
C01064 00194 ∂09-Aug-85 1623 @MIT-MC.ARPA:JINX@MIT-OZ Altering quoted structure
C01066 00195 ∂12-Aug-85 0745 JAR@MIT-MC.ARPA delay, force, cons-stream
C01067 00196 ∂16-Sep-85 1306 JAR@MIT-MC.ARPA report scheme in CL trace
C01071 00197 ∂17-Sep-85 1312 @MIT-MC.ARPA:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: report scheme in CL trace
C01074 00198 ∂22-Oct-85 2253 @MIT-MC.ARPA:meltsner%athena@mit-eddie.MIT.EDU Scheme for Thermo.
C01078 00199 ∂22-Oct-85 2253 JAR@MIT-MC.ARPA scheme implementations
C01081 00200 ∂22-Oct-85 2334 JAR@MIT-MC.ARPA welcome
C01084 00201 ∂22-Oct-85 2351 JAR@MIT-MC.ARPA Implementation blurb: Scheme in Common Lisp
C01087 00202 ∂23-Oct-85 2107 JAR@MIT-MC.ARPA Implementation blurb: Vincennes Scheme
C01089 00203 ∂23-Oct-85 2322 @MIT-MC.ARPA:narain@rand-unix.ARPA Elementary question about backquote in T.
C01092 00204 ∂24-Oct-85 0856 @MIT-MC.ARPA:gls@THINK-AQUINAS.ARPA Elementary question about backquote in T.
C01097 00205 ∂24-Oct-85 1201 @MIT-MC.ARPA:RAM@YALE.ARPA Re: Elementary question about backquote in T.
C01102 00206 ∂24-Oct-85 1331 JAR@MIT-MC.ARPA T mailing lists.
C01104 00207 ∂24-Oct-85 1443 @MIT-MC.ARPA:narain@rand-unix.ARPA Q. on backquote
C01106 00208 ∂25-Oct-85 0945 @MIT-MC.ARPA:HUDAK@YALE.ARPA Re: Q. on backquote
C01108 00209 ∂26-Oct-85 1019 @MIT-MC.ARPA:WAXMAN@USC-ECL.ARPA PLASE REMOVE MY NAME FROM SCHEME MAILING LIST
C01109 00210 ∂28-Oct-85 0740 JAR@MIT-MC.ARPA moderation
C01112 00211 ∂28-Oct-85 0824 JAR@MIT-MC.ARPA implementations
C01119 00212 ∂28-Oct-85 1024 JAR@MIT-MC.ARPA implementations
C01126 00213 ∂28-Oct-85 1158 @MIT-MC.ARPA:narain@rand-unix.ARPA Re: moderation
C01129 00214 ∂28-Oct-85 1359 @MIT-MC.ARPA:bap@g.cs.cmu.edu Re: need for quoting in Lisp
C01135 00215 ∂28-Oct-85 1441 GJC@MIT-MC.ARPA
C01139 00216 ∂28-Oct-85 1457 GJC@MIT-MC.ARPA moderation
C01141 00217 ∂28-Oct-85 1542 @MIT-MC.ARPA:JINX@MIT-OZ moderation
C01146 00218 ∂28-Oct-85 1627 @MIT-MC.ARPA:HAL@MIT-OZ quote
C01152 00219 ∂28-Oct-85 1720 @MIT-MC.ARPA:SRIDHARAN@BBNG.ARPA Why quote?
C01157 00220 ∂28-Oct-85 1816 @MIT-MC.ARPA:JINX@MIT-OZ quote
C01159 00221 ∂29-Oct-85 0816 @MIT-MC.ARPA:gls@THINK-AQUINAS.ARPA Re: need for quoting in Lisp
C01162 00222 ∂29-Oct-85 0842 JAR@MIT-MC.ARPA administrivia
C01164 00223 ∂29-Oct-85 1231 @MIT-MC.ARPA:cpd@LOCUS.UCLA.EDU Continuations
C01166 00224 ∂30-Oct-85 0750 @MIT-MC.ARPA:HUDAK@YALE.ARPA Re: moderation
C01169 00225 ∂30-Oct-85 0909 @MIT-MC.ARPA:cpd@LOCUS.UCLA.EDU Re: Continuations
C01174 00226 ∂30-Oct-85 1206 @MIT-MC.ARPA:JINX@MIT-OZ Continuations
C01178 00227 ∂30-Oct-85 1351 @MIT-MC.ARPA:HUDAK@YALE.ARPA will the real current continuation please stand up
C01181 00228 ∂30-Oct-85 1410 JAR@MIT-MC.ARPA Continuations
C01184 00229 ∂30-Oct-85 1503 JAR@MIT-MC.ARPA will the real current continuation please stand up
C01186 00230 ∂30-Oct-85 1800 @MIT-MC.ARPA:JINX@MIT-OZ will the real current continuation please stand up
C01189 00231 ∂30-Oct-85 1827 @MIT-MC.ARPA:HUDAK@YALE.ARPA Re: will the real current continuation please stand up
C01191 00232 ∂31-Oct-85 1024 @MIT-MC.ARPA:dyb%indiana.csnet@CSNET-RELAY.ARPA Scheme Implementation Blurb: Chez Scheme
C01196 00233 ∂01-Nov-85 1351 @MIT-MC.ARPA:HUDAK@YALE.ARPA Re: will the real current continuation please stand up
C01199 00234 ∂08-Nov-85 1809 @MIT-MC.ARPA:BARTLEY%ti-csl.csnet@CSNET-RELAY.ARPA Syntactic extensions to Scheme
C01202 00235 ∂12-Nov-85 1334 @MIT-MC.ARPA:OXLEY%ti-csl.csnet@CSNET-RELAY.ARPA PC Scheme Implementation Information
C01210 00236 ∂12-Nov-85 1905 JAR@MIT-MC.ARPA test message
C01211 00237 ∂13-Nov-85 1618 JAR@MIT-MC.ARPA a modest backquote proposal
C01218 00238 ∂14-Nov-85 1020 JAR@MIT-MC.ARPA Syntactic extensions to Scheme
C01236 00239 ∂14-Nov-85 1559 @MIT-MC.ARPA:JINX@MIT-OZ Syntactic extensions to Scheme (long message)
C01244 00240 ∂14-Nov-85 2150 @MIT-MC.ARPA:CPH@MIT-OZ Syntactic extensions to Scheme
C01256 00241 ∂15-Nov-85 1251 JAR@MIT-MC.ARPA testing, testing, ...
C01258 00242 ∂17-Nov-85 1547 @MIT-MC.ARPA:linus!ramsdell@mitre-bedford.ARPA Stream command processing (long message)
C01272 00243 ∂18-Nov-85 1710 @MIT-MC.ARPA:linus!ramsdell@mitre-bedford.ARPA read-cstream fix
C01274 00244 ∂18-Nov-85 1744 @MIT-MC.ARPA:JINX@MIT-OZ Stream command processing (long message)
C01276 00245 ∂18-Nov-85 1828 @MIT-MC.ARPA:JINX@MIT-OZ Stream command processing (long message)
C01280 00246 ∂18-Nov-85 1846 @MIT-MC.ARPA:JINX@MIT-OZ Incomplete message
C01281 00247 ∂19-Nov-85 1327 JAR@MIT-MC.ARPA backquote proposal
C01284 00248 ∂20-Nov-85 0901 @MIT-MC.ARPA:BARTLEY%ti-csl.csnet@CSNET-RELAY.ARPA Re: backquote proposal
C01286 00249 ∂20-Nov-85 1214 @MIT-MC.ARPA:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: backquote proposal
C01289 00250 ∂20-Nov-85 1326 JAR@MIT-MC.ARPA backquote proposal
C01294 00251 ∂20-Nov-85 1333 JAR@MIT-MC.ARPA Backquote algorithm
C01301 00252 ∂20-Nov-85 1743 @MIT-MC.ARPA:BARTLEY%ti-csl.csnet@CSNET-RELAY.ARPA Multiple LAMBDA evaluations
C01304 00253 ∂20-Nov-85 2352 @MIT-MC.ARPA:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA trace
C01308 00254 ∂21-Nov-85 0745 @MIT-MC.ARPA:JINX@MIT-OZ trace
C01313 00255 ∂21-Nov-85 0903 JAR@MIT-MC.ARPA description of MacScheme
C01317 00256 ∂21-Nov-85 0920 JAR@MIT-MC.ARPA Multiple LAMBDA evaluations
C01322 00257 ∂21-Nov-85 1306 @MIT-MC.ARPA:dyb%indiana.csnet@CSNET-RELAY.ARPA re: backquote
C01324 00258 ∂21-Nov-85 1324 JAR@MIT-MC.ARPA trace
C01328 00259 ∂21-Nov-85 1324 @MIT-MC.ARPA:CPH@MIT-OZ trace
C01330 00260 ∂21-Nov-85 1324 @MIT-MC.ARPA:JINX@MIT-OZ Multiple LAMBDA evaluations
C01332 00261 ∂21-Nov-85 1805 @MIT-MC.ARPA:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA EQ? and procedures, numbers, etc
C01335 00262 ∂21-Nov-85 1926 @MIT-MC.ARPA:BARTLEY%ti-csl.csnet@CSNET-RELAY.ARPA Re: Multiple LAMBDA evaluations
C01339 00263 ∂21-Nov-85 2015 @MIT-MC.ARPA:JINX@MIT-OZ Multiple LAMBDA evaluations
C01342 00264 ∂22-Nov-85 1054 @MIT-MC.ARPA:BARTLEY%ti-csl.csnet@CSNET-RELAY.ARPA Re: Multiple LAMBDA evaluations
C01347 00265 ∂22-Nov-85 1135 @MIT-MC.ARPA:KMP@SCRC-STONY-BROOK.ARPA EQ? and procedures, numbers, etc
C01353 00266 ∂22-Nov-85 1515 @MIT-MC.ARPA:gls@THINK-AQUINAS.ARPA EQ? and procedures, numbers, etc
C01358 00267 ∂22-Nov-85 1628 @MIT-MC.ARPA:adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: trace
C01362 00268 ∂22-Nov-85 2038 @MIT-MC.ARPA:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: backquote proposal
C01364 00269 ∂22-Nov-85 2101 @MIT-MC.ARPA:JINX@MIT-OZ Multiple LAMBDA evaluations
C01367 00270 ∂22-Nov-85 2157 @MIT-MC.ARPA:JINX@MIT-OZ trace
C01372 00271 ∂25-Nov-85 1133 @MIT-MC.ARPA:KMP@SCRC-STONY-BROOK.ARPA EQ? and procedures, numbers, etc
C01377 00272 ∂25-Nov-85 1426 @MIT-MC.ARPA:JINX@MIT-OZ EQ? and procedures, numbers, etc
C01379 00273 ∂25-Nov-85 1551 @MIT-MC.ARPA:adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA trace, language vs. implementation
C01384 00274 ∂25-Nov-85 1802 @MIT-MC.ARPA:adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: trace
C01390 00275 ∂25-Nov-85 1812 @MIT-MC.ARPA:JINX@MIT-OZ trace, language vs. implementation
C01396 00276 ∂26-Nov-85 0049 @MIT-MC.ARPA:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA EQ? and procedures etc
C01414 00277 ∂26-Nov-85 0953 @MIT-MC.ARPA:gls@THINK-AQUINAS.ARPA EQ? and procedures etc
C01429 00278 ∂26-Nov-85 1201 JAR@MIT-MC.ARPA EQV? and procedures etc
C01433 00279 ∂27-Nov-85 2057 @MIT-MC.ARPA:wagle%indiana.csnet@CSNET-RELAY.ARPA EQ? on pointers to functions
C01439 00280 ∂04-Dec-85 1518 @MIT-MC.ARPA:msr@rice.ARPA Query: Scheme on a Sun?
C01440 00281 ∂12-Dec-85 1515 @MIT-MC.ARPA:gls@THINK-AQUINAS.ARPA [Postmaster@SCRC-STONY-BROOK.ARPA: Unable to deliver letter]
C01445 00282 ∂13-Dec-85 1355 @MIT-MC.ARPA:gls@THINK-AQUINAS.ARPA EQ? again, already
C01448 00283 ∂13-Dec-85 1850 JAR@MIT-MC.ARPA EQ? again, already
C01453 00284 ∂13-Dec-85 1854 JAR@MIT-MC.ARPA EQ? again, already
C01454 00285 ∂14-Dec-85 0603 @MIT-MC.ARPA:HAL@MIT-OZ intro computer science course at Brandeis
C01480 00286 ∂15-Dec-85 1641 JAR@MIT-MC.ARPA [CPH%MIT-OZ: HP 300s]
C01483 00287 ∂15-Dec-85 1919 JAR@MIT-MC.ARPA backquote
C01490 00288 ∂20-Dec-85 1153 @MC.LCS.MIT.EDU:CPH@OZ.AI.MIT.EDU Editors used with Scheme
C01492 00289 ∂20-Dec-85 1153 @MC.LCS.MIT.EDU:duke@mitre.ARPA Editors used with Scheme
C01494 00290 ∂21-Jan-86 1150 @MC.LCS.MIT.EDU:marick%fang@gswd-vms Industrial-strength Scheme class.
C01497 00291 ∂21-Jan-86 1446 @MC.LCS.MIT.EDU:HAL%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Industrial-strength Scheme class.
C01499 00292 ∂23-Jan-86 1301 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: Industrial-strength Scheme class.
C01503 00293 ∂24-Jan-86 0827 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA quasiquote implementation
C01508 00294 ∂24-Jan-86 1252 JAR@MC.LCS.MIT.EDU quasiquote implementation
C01510 00295 ∂25-Jan-86 1155 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: quasiquote implementation
C01517 00296 ∂28-Jan-86 1108 @MC.LCS.MIT.EDU:ram%YALE-RING@YALE.ARPA Of growing code and diminishing hacks...
C01523 00297 ∂28-Jan-86 2352 @MC.LCS.MIT.EDU:Miller.pa@Xerox.COM Re: Of growing code and diminishing hacks...
C01525 00298 ∂29-Jan-86 0121 @MC.LCS.MIT.EDU:Miller.pa@Xerox.COM Re: Of growing code and diminishing hacks...
C01527 00299 ∂29-Jan-86 0558 GJC@MC.LCS.MIT.EDU Overloading of empty list as false.
C01531 00300 ∂29-Jan-86 1049 @MC.LCS.MIT.EDU:ram%YALE-RING@YALE.ARPA Re: Of growing code and diminishing hacks...
C01534 00301 ∂29-Jan-86 1119 @MC.LCS.MIT.EDU:ram%YALE-RING@YALE.ARPA Re: Of growing code and diminishing hacks...
C01536 00302 ∂11-Feb-86 0420 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Which constants must be quoted?
C01542 00303 ∂12-Feb-86 1803 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Which constants must be quoted?
C01545 00304 ∂13-Feb-86 1147 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: Which constants must be quoted?
C01548 00305 ∂13-Feb-86 1257 JAR@MC.LCS.MIT.EDU Which constants must be quoted?
C01555 00306 ∂14-Feb-86 0711 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Which constants must be quoted?
C01558 00307 ∂14-Feb-86 0944 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Which constants must be quoted?
C01560 00308 ∂14-Feb-86 1638 @MC.LCS.MIT.EDU:KMP@SCRC-STONY-BROOK.ARPA Which constants must be quoted?
C01563 00309 ∂14-Feb-86 2300 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Which constants must be quoted?
C01565 00310 ∂17-Feb-86 1648 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Jonathan Rees for editor
C01570 00311 ∂17-Feb-86 1946 JAR@MC.LCS.MIT.EDU quotation
C01576 00312 ∂19-Feb-86 1839 JAR@MC.LCS.MIT.EDU EQ?, again
C01580 00313 ∂19-Feb-86 2209 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: quotation
C01583 00314 ∂20-Feb-86 0713 @MC.LCS.MIT.EDU:KMP@SCRC-STONY-BROOK.ARPA EQ?, again
C01589 00315 ∂20-Feb-86 1147 JAR@MC.LCS.MIT.EDU EQV? note
C01591 00316 ∂20-Feb-86 1157 JAR@MC.LCS.MIT.EDU survey - JAR's answers
C01594 00317 ∂20-Feb-86 1157 JAR@MC.LCS.MIT.EDU EQV? note (tiny correction)
C01595 00318 ∂20-Feb-86 1450 JAR@MC.LCS.MIT.EDU further clarification
C01601 00319 ∂20-Feb-86 1737 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA publication of RRRS in SIGPLAN Notices
C01604 00320 ∂21-Feb-86 0529 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA proposing changes to RRRS
C01612 00321 ∂21-Feb-86 1337 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU proposing changes to RRRS
C01616 00322 ∂21-Feb-86 1407 JAR@MC.LCS.MIT.EDU proposing changes to RRRS
C01622 00323 ∂21-Feb-86 2249 @MC.LCS.MIT.EDU:OXLEY%%ti-csl.csnet@CSNET-RELAY.ARPA Who Is Using Scheme? For What?
C01627 00324 ∂21-Feb-86 2345 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA EQ? Survey Entry
C01632 00325 ∂22-Feb-86 0547 @MC.LCS.MIT.EDU:adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: survey - JAR's answers
C01635 00326 ∂22-Feb-86 0550 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: EQ?, again
C01639 00327 ∂22-Feb-86 1517 @MC.LCS.MIT.EDU:fickas%uo-vax1%uoregon.csnet@CSNET-RELAY.ARPA Use of MacScheme
C01642 00328 ∂23-Feb-86 1454 @MC.LCS.MIT.EDU:skrzypek@LOCUS.UCLA.EDU SCHEME based PC Vision Station
C01644 00329 ∂24-Feb-86 0816 @MC.LCS.MIT.EDU:Swenson.Multics@CISL-SERVICE-MULTICS.ARPA Re: Who Is Using Scheme? For What?
C01647 00330 ∂24-Feb-86 0842 NET-ORIGIN@MC.LCS.MIT.EDU EQ?, again
C01655 00331 ∂24-Feb-86 0922 @MC.LCS.MIT.EDU:allen@BBNJ.ARPA Butterfly Lisp
C01657 00332 ∂24-Feb-86 0953 @MC.LCS.MIT.EDU:OXLEY%ti-csl.csnet@CSNET-RELAY.ARPA Re: Who Is Using Scheme? For What?
C01662 00333 ∂24-Feb-86 1131 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU named-lambda
C01664 00334 ∂24-Feb-86 1536 @MC.LCS.MIT.EDU:Haddock%ti-csl.csnet@CSNET-RELAY.ARPA Re: Who Is Using Scheme? For What?
C01667 00335 ∂24-Feb-86 1833 @MC.LCS.MIT.EDU:Swenson.Multics@cisl-service-multics.ARPA Re: Who Is Using Scheme? For What?
C01669 00336 ∂24-Feb-86 1854 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU numeric predicates
C01670 00337 ∂24-Feb-86 1904 JAR@MC.LCS.MIT.EDU flush object-hash
C01671 00338 ∂24-Feb-86 1921 @MC.LCS.MIT.EDU:GJS%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Re: numeric predicates
C01673 00339 ∂24-Feb-86 2117 @MC.LCS.MIT.EDU:ucsbcsl!image!zeger@ucbvax.berkeley.edu Re: Who is using Scheme? For What?
C01676 00340 ∂24-Feb-86 2330 @MC.LCS.MIT.EDU:andy@aids-unix Scheme use
C01682 00341 ∂25-Feb-86 0340 @MC.LCS.MIT.EDU:TIM%upenn.csnet@CSNET-RELAY.ARPA who's using Scheme
C01684 00342 ∂25-Feb-86 0451 @MC.LCS.MIT.EDU:ramsdell%linus@mitre-bedford.ARPA named-lambda
C01686 00343 ∂25-Feb-86 0544 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU numeric predicates
C01688 00344 ∂25-Feb-86 1216 JAR@MC.LCS.MIT.EDU Things used in S&ICP
C01691 00345 ∂25-Feb-86 1527 @MC.LCS.MIT.EDU:Camp%ti-csl.csnet@CSNET-RELAY.ARPA PC SCHEME UTILITIES AND ON-LINE HELP
C01699 00346 ∂25-Feb-86 1547 @MC.LCS.MIT.EDU:Ferguson%ti-csl.csnet@CSNET-RELAY.ARPA Re: Who Is Using Scheme? For What?
C01702 00347 ∂25-Feb-86 1657 JAR@MC.LCS.MIT.EDU EQ? non-essential?
C01706 00348 ∂25-Feb-86 2136 @MC.LCS.MIT.EDU:cpd@LOCUS.UCLA.EDU Re: Who is using scheme?
C01708 00349 ∂25-Feb-86 2341 @MC.LCS.MIT.EDU:entropy!jam@uw-beaver.arpa Scheme for a Symbolics
C01710 00350 ∂26-Feb-86 1243 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: Things used in S&ICP
C01714 00351 ∂26-Feb-86 1313 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: EQ? non-essential?
C01719 00352 ∂27-Feb-86 0941 @MC.LCS.MIT.EDU:veach%ukans.csnet@CSNET-RELAY.ARPA Use of Scheme.
C01723 00353 ∂27-Feb-86 1226 @MC.LCS.MIT.EDU:JBS@DEEP-THOUGHT.MIT.EDU Use of Scheme.
C01725 00354 ∂27-Feb-86 1519 JAR@MC.LCS.MIT.EDU Scheme in Common Lisp
C01729 00355 ∂27-Feb-86 1548 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: named-lambda, etc
C01734 00356 ∂27-Feb-86 1615 @MC.LCS.MIT.EDU,@SU-SCORE.ARPA:starbuck@camelot Scheme use
C01738 00357 ∂28-Feb-86 0354 @MC.LCS.MIT.EDU:JMILLER@OZ.AI.MIT.EDU Re: named-lambda, etc
C01741 00358 ∂28-Feb-86 1158 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA publication of RRRS in SIGPLAN Notices
C01743 00359 ∂28-Feb-86 1204 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA numeric predicates
C01746 00360 ∂28-Feb-86 1526 JAR@MC.LCS.MIT.EDU EQ?, again
C01749 00361 ∂28-Feb-86 1610 @MC.LCS.MIT.EDU:KMP@SCRC-STONY-BROOK.ARPA P?
C01756 00362 ∂28-Feb-86 1610 JAR@MC.LCS.MIT.EDU S&I's idea of EQ?
C01760 00363 ∂28-Feb-86 1817 JAR@MC.LCS.MIT.EDU named-lambda, etc
C01761 00364 ∂28-Feb-86 1831 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA EQ?, again
C01764 00365 ∂28-Feb-86 1831 ALAN@MC.LCS.MIT.EDU numeric predicates
C01766 00366 ∂28-Feb-86 2307 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU named-lambda, etc
C01768 00367 ∂28-Feb-86 2323 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU named-lambda, etc
C01772 00368 ∂01-Mar-86 2333 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU%mc.lcs.mit.edu@CSNET-RELAY.ARPA EQ? non-essential?
C01776 00369 ∂02-Mar-86 2128 @MC.LCS.MIT.EDU:dfried%indiana.csnet@CSNET-RELAY.ARPA rec
C01779 00370 ∂03-Mar-86 0835 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA EQ?, again
C01782 00371 ∂03-Mar-86 0847 @MC.LCS.MIT.EDU:SIG%CARLETON.BITNET@wiscvm.wisc.edu We are using scheme!
C01786 00372 ∂03-Mar-86 1035 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU rec
C01789 00373 ∂03-Mar-86 1150 @MC.LCS.MIT.EDU:sas@BBN-VAX.ARPA COMMON LISP is the PL/I of LISPs
C01791 00374 ∂03-Mar-86 1223 @MC.LCS.MIT.EDU:KMP@SCRC-STONY-BROOK.ARPA P?
C01796 00375 ∂03-Mar-86 1227 NET-ORIGIN@MC.LCS.MIT.EDU "splitting" in multiprocessors
C01801 00376 ∂03-Mar-86 1301 @MC.LCS.MIT.EDU:SMC%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU COMMON LISP is the PL/I of LISPs
C01805 00377 ∂03-Mar-86 1521 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA COMMON LISP is the PL/I of LISPs
C01808 00378 ∂04-Mar-86 0753 @MC.LCS.MIT.EDU:Jensen%ti-csl.csnet@CSNET-RELAY.ARPA PC Scheme Information
C01811 00379 ∂04-Mar-86 1347 YEKTA@MC.LCS.MIT.EDU PC Scheme Information
C01812 00380 ∂05-Mar-86 1515 JAR@MC.LCS.MIT.EDU #!null
C01815 00381 ∂05-Mar-86 1812 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU #!null
C01817 00382 ∂10-Mar-86 1455 JAR@MC.LCS.MIT.EDU NIHIL EX NIHIL - DON'T SETQ NIL
C01821 00383 ∂12-Mar-86 0325 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: NIHIL EX NIHIL - DON'T SETQ NIL
C01824 00384 ∂12-Mar-86 0339 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA S&I's idea of EQ?
C01833 00385 ∂13-Mar-86 0437 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@mc.lcs.mit.edu S&I's idea of EQ? (long)
C01844 00386 ∂13-Mar-86 0440 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: S&I's idea of EQ?
C01848 00387 ∂13-Mar-86 0754 @MC.LCS.MIT.EDU:harrison@nrl-aic mailing list
C01850 00388 ∂13-Mar-86 0859 @MC.LCS.MIT.EDU:harrison@nrl-aic corrected address
C01851 00389 ∂13-Mar-86 1404 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: S&I's idea of EQ? (long)
C01857 00390 ∂13-Mar-86 1424 JAR@MC.LCS.MIT.EDU survey results (long message)
C01867 00391 ∂13-Mar-86 1453 @MC.LCS.MIT.EDU:rjk@mitre-bedford.ARPA Unexpected Message
C01869 00392 ∂13-Mar-86 1508 JAR@MC.LCS.MIT.EDU S&I's idea of EQ?
C01870 00393 ∂13-Mar-86 1546 JAR@MC.LCS.MIT.EDU S&I's idea of EQ?
C01873 00394 ∂13-Mar-86 1615 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU S&I's idea of EQ?
C01876 00395 ∂14-Mar-86 0311 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: S&I's idea of EQ? (long)
C01880 00396 ∂14-Mar-86 0937 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: S&I's idea of EQ?
C01885 00397 ∂14-Mar-86 1218 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: S&I's idea of EQ? (OOPS!)
C01887 00398 ∂17-Mar-86 1644 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: S&I's idea of EQ?
C01893 00399 ∂17-Mar-86 1840 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU S&I's idea of EQ?
C01899 00400 ∂18-Mar-86 2105 @MC.LCS.MIT.EDU:hsc8r120006%uhcl.csnet@CSNET-RELAY.ARPA scheme community
C01901 00401 ∂19-Mar-86 1648 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: S&I's idea of EQ?
C01909 00402 ∂20-Mar-86 0334 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@mc.lcs.mit.edu S&I's idea of EQ?
C01915 00403 ∂21-Mar-86 0320 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: S&I's idea of EQ?
C01923 00404 ∂21-Mar-86 0849 @MC.LCS.MIT.EDU:LSI.RAY@SPEECH.MIT.EDU A chipmunk scheme compiler
C01925 00405 ∂21-Mar-86 1101 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU A chipmunk scheme compiler
C01927 00406 ∂21-Mar-86 1326 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: S&I's idea of EQ?
C01931 00407 ∂21-Mar-86 1530 @MC.LCS.MIT.EDU:FACCROSS%WSUVM1.BITNET@WISCVM.WISC.EDU
C01933 00408 ∂25-Mar-86 0323 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU S&I's idea of EQ?
C01936 00409 ∂25-Mar-86 0327 JAR@MC.LCS.MIT.EDU small changes
C01940 00410 ∂25-Mar-86 0328 JAR@MC.LCS.MIT.EDU Scheme BNF
C01952 00411 ∂25-Mar-86 0335 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@mc.lcs.mit.edu S&I's idea of EQ?
C01959 00412 ∂25-Mar-86 0342 @MC.LCS.MIT.EDU:F.AE@DEEP-THOUGHT.MIT.EDU Scheme implementation guide
C01961 00413 ∂25-Mar-86 0351 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU small changes
C01963 00414 ∂25-Mar-86 0352 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU small changes
C01966 00415 ∂25-Mar-86 0351 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA Scheme BNF
C01972 00416 ∂25-Mar-86 0351 @MC.LCS.MIT.EDU:MHWU%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Partisans of NAMED-LAMBDA
C01974 00417 ∂25-Mar-86 0351 @MC.LCS.MIT.EDU:ramsdell%linus@mitre-bedford.ARPA Expunge LETREC, BEGIN and SEQUENCE.
C01977 00418 ∂25-Mar-86 0353 @MC.LCS.MIT.EDU:OXLEY%ti-csl.csnet@CSNET-RELAY.ARPA Re: Scheme BNF
C01979 00419 ∂25-Mar-86 0353 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: Scheme BNF
C01985 00420 ∂25-Mar-86 0352 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU small changes
C01989 00421 ∂25-Mar-86 0352 ALAN@MC.LCS.MIT.EDU small changes
C01992 00422 ∂25-Mar-86 0353 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Expunge LETREC, BEGIN and SEQUENCE.
C01994 00423 ∂25-Mar-86 0353 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: small changes
C02000 00424 ∂25-Mar-86 0408 JAR@MC.LCS.MIT.EDU small changes
C02003 00425 ∂25-Mar-86 0509 JAR@MC.LCS.MIT.EDU small changes
C02006 00426 ∂25-Mar-86 0525 JAR@MC.LCS.MIT.EDU Scheme implementation guide
C02008 00427 ∂25-Mar-86 0541 JAR@MC.LCS.MIT.EDU Scheme BNF
C02010 00428 ∂25-Mar-86 0723 @MC.LCS.MIT.EDU:ramsdell%linus@mitre-bedford.ARPA Expunge NAMED-LAMBDA
C02012 00429 ∂25-Mar-86 1258 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: small changes
C02018 00430 ∂25-Mar-86 1303 JAR@MC.LCS.MIT.EDU (do ((var init)) (...))
C02021 00431 ∂26-Mar-86 0609 @MC.LCS.MIT.EDU:abc%computer-science.nottingham.ac.uk@Cs.Ucl.AC.UK Scheme wanted
C02023 00432 ∂26-Mar-86 0717 JAR@MC.LCS.MIT.EDU small changes
C02025 00433 ∂26-Mar-86 1319 JAR@MC.LCS.MIT.EDU another nit
C02029 00434 ∂26-Mar-86 1445 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU another nit
C02031 00435 ∂26-Mar-86 2247 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU small changes
C02036 00436 ∂27-Mar-86 0126 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Scheme BNF
C02042 00437 ∂27-Mar-86 1142 JAR@MC.LCS.MIT.EDU Scheme BNF
C02048 00438 ∂27-Mar-86 1242 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Scheme BNF
C02050 00439 ∂27-Mar-86 1319 JAR@MC.LCS.MIT.EDU meaning of local define
C02055 00440 ∂27-Mar-86 1434 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA small changes
C02059 00441 ∂27-Mar-86 1436 JAR@MC.LCS.MIT.EDU meaning of local define (tiny correction)
C02060 00442 ∂27-Mar-86 1450 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA meaning of local define
C02063 00443 ∂27-Mar-86 1736 @MC.LCS.MIT.EDU:adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA NAMED-LAMBDA, REC, DEFINE
C02068 00444 ∂27-Mar-86 1740 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: another nit
C02072 00445 ∂27-Mar-86 1825 JAR@MC.LCS.MIT.EDU another nit
C02078 00446 ∂28-Mar-86 0706 @MC.LCS.MIT.EDU:duke@mitre.ARPA A bug in my version of MIT Scheme
C02080 00447 ∂28-Mar-86 0835 NET-ORIGIN@MC.LCS.MIT.EDU self-reference and DEFINE
C02083 00448 ∂28-Mar-86 1319 @MC.LCS.MIT.EDU:LS.JINX@DEEP-THOUGHT.MIT.EDU meaning of local define
C02088 00449 ∂29-Mar-86 1326 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Scheme BNF
C02090 00450 ∂29-Mar-86 1343 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU meaning of local define
C02094 00451 ∂29-Mar-86 1346 JAR@MC.LCS.MIT.EDU small changes
C02106 00452 ∂29-Mar-86 1350 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU small changes
C02108 00453 ∂29-Mar-86 1353 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU NAMED-LAMBDA, REC, DEFINE
C02110 00454 ∂29-Mar-86 1355 JAR@MC.LCS.MIT.EDU meaning of local define
C02113 00455 ∂29-Mar-86 1405 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU meaning of local define
C02115 00456 ∂29-Mar-86 1439 JAR@MC.LCS.MIT.EDU Scheme BNF
C02120 00457 ∂29-Mar-86 1532 JAR@MC.LCS.MIT.EDU Scheme BNF
C02126 00458 ∂29-Mar-86 1705 JAR@MC.LCS.MIT.EDU meaning of local define
C02129 00459 ∂29-Mar-86 1718 JAR@MC.LCS.MIT.EDU NAMED-LAMBDA, REC, DEFINE
C02132 00460 ∂29-Mar-86 2011 JAR@MC.LCS.MIT.EDU (EQV? '(A) '(A))
C02135 00461 ∂29-Mar-86 2113 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU small changes
C02139 00462 ∂29-Mar-86 2122 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU meaning of local define
C02142 00463 ∂29-Mar-86 2147 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU (EQV? '(A) '(A))
C02145 00464 ∂30-Mar-86 0902 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU NAMED-LAMBDA, REC, DEFINE
C02147 00465 ∂30-Mar-86 1310 JAR@MC.LCS.MIT.EDU [dfried%indiana.csnet: boolean?]
C02149 00466 ∂30-Mar-86 1347 JAR@MC.LCS.MIT.EDU mail to scheme@mc
C02151 00467 ∂30-Mar-86 1927 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU [dfried%indiana.csnet: boolean?]
C02153 00468 ∂30-Mar-86 2059 @MC.LCS.MIT.EDU:ANDY@SU-SUSHI.ARPA immutable structures
C02155 00469 ∂30-Mar-86 2241 @MC.LCS.MIT.EDU:Miller.pa@Xerox.COM non-list arguments
C02157 00470 ∂30-Mar-86 2256 @MC.LCS.MIT.EDU:FAHLMAN@C.CS.CMU.EDU non-list arguments
C02159 00471 ∂31-Mar-86 0032 @MC.LCS.MIT.EDU:Miller.pa@Xerox.COM Re: non-list arguments
C02161 00472 ∂31-Mar-86 0046 @MC.LCS.MIT.EDU:FAHLMAN@C.CS.CMU.EDU non-list arguments
C02164 00473 ∂31-Mar-86 0104 ALAN@MC.LCS.MIT.EDU non-list arguments
C02167 00474 ∂31-Mar-86 0402 @MC.LCS.MIT.EDU:ramsdell%linus@mitre-bedford.ARPA Denotational semantics for SIGPLAN?
C02169 00475 ∂31-Mar-86 0733 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU non-list arguments
C02171 00476 ∂31-Mar-86 0813 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA Scheme BNF
C02174 00477 ∂31-Mar-86 0829 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA meaning of local define
C02177 00478 ∂31-Mar-86 1024 @MC.LCS.MIT.EDU:ANDY@SU-SUSHI.ARPA immutable structures
C02179 00479 ∂31-Mar-86 1051 JAR@MC.LCS.MIT.EDU meaning of local define
C02183 00480 ∂31-Mar-86 1055 JAR@MC.LCS.MIT.EDU (BEGIN)
C02185 00481 ∂31-Mar-86 1058 JAR@MC.LCS.MIT.EDU Denotational semantics for SIGPLAN?
C02187 00482 ∂31-Mar-86 1352 JAR@MC.LCS.MIT.EDU non-list arguments
C02189 00483 ∂31-Mar-86 1541 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU (BEGIN)
C02191 00484 ∂31-Mar-86 1701 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU meaning of local define
C02197 00485 ∂31-Mar-86 1722 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU LETREC (REC)
C02199 00486 ∂31-Mar-86 2309 @MC.LCS.MIT.EDU:KMP@SCRC-STONY-BROOK.ARPA Scheme BNF
C02203 00487 ∂01-Apr-86 0007 @MC.LCS.MIT.EDU:KMP@SCRC-STONY-BROOK.ARPA New special forms -- CALL and VAR (or some such)
C02208 00488 ∂01-Apr-86 0523 @MC.LCS.MIT.EDU:KWH@AI.AI.MIT.EDU LETREC (REC)
C02211 00489 ∂01-Apr-86 0650 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU LETREC (REC)
C02215 00490 ∂01-Apr-86 0653 NET-ORIGIN@MC.LCS.MIT.EDU #t and #f
C02217 00491 ∂01-Apr-86 0722 @MC.LCS.MIT.EDU:kelsey@YALE.ARPA #t, #f, and (BEGIN)
C02219 00492 ∂01-Apr-86 0904 NET-ORIGIN@MC.LCS.MIT.EDU meaning of local define
C02224 00493 ∂01-Apr-86 0911 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU MIT Scheme, general information (long message)
C02231 00494 ∂01-Apr-86 1043 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: small changes
C02233 00495 ∂01-Apr-86 1110 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Case Sensitivity
C02236 00496 ∂01-Apr-86 1239 GJC@MC.LCS.MIT.EDU MIT Scheme, linking C compiler output.
C02238 00497 ∂01-Apr-86 1302 NET-ORIGIN@MC.LCS.MIT.EDU non-list arguments
C02243 00498 ∂01-Apr-86 1840 JAR@MC.LCS.MIT.EDU changes
C02247 00499 ∂01-Apr-86 2058 JAR@MC.LCS.MIT.EDU begin
C02249 00500 ∂01-Apr-86 2109 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU LETREC (REC)
C02251 00501 ∂01-Apr-86 2111 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU LETREC (REC)
C02253 00502 ∂02-Apr-86 0017 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: immutable structures
C02257 00503 ∂02-Apr-86 1004 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU begin
C02260 00504 ∂02-Apr-86 1033 JAR@MC.LCS.MIT.EDU begin
C02264 00505 ∂02-Apr-86 1051 @MC.LCS.MIT.EDU:KMP@SCRC-STONY-BROOK.ARPA begin
C02269 00506 ∂02-Apr-86 1033 JAR@MC.LCS.MIT.EDU LETREC (REC)
C02271 00507 ∂02-Apr-86 1102 JAR@MC.LCS.MIT.EDU begin
C02274 00508 ∂02-Apr-86 1338 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU begin
C02277 00509 ∂02-Apr-86 1352 JAR@MC.LCS.MIT.EDU expansion of LETREC
C02284 00510 ∂02-Apr-86 1354 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU begin
C02286 00511 ∂02-Apr-86 1508 NET-ORIGIN@MC.LCS.MIT.EDU expansion of LETREC
C02289 00512 ∂02-Apr-86 1625 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU expansion of LETREC
C02291 00513 ∂03-Apr-86 0737 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA non-list arguments
C02294 00514 ∂03-Apr-86 0822 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA begin
C02297 00515 ∂03-Apr-86 0929 @MC.LCS.MIT.EDU:hudak@YALE.ARPA Re: expansion of LETREC
C02301 00516 ∂03-Apr-86 1139 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU expansion of LETREC
C02303 00517 ∂03-Apr-86 1154 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU expansion of LETREC
C02305 00518 ∂04-Apr-86 1334 @MC.LCS.MIT.EDU:Pase.CCS@DOCKMASTER.ARPA Scheme for the Atari ST
C02307 00519 ∂04-Apr-86 1413 @MC.LCS.MIT.EDU:KWH@AI.AI.MIT.EDU LETREC (REC)
C02311 00520 ∂04-Apr-86 1448 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU LETREC (REC)
C02314 00521 ∂04-Apr-86 1821 @MC.LCS.MIT.EDU:ANDY@SU-SUSHI.ARPA Immutable code and quoted data
C02323 00522 ∂04-Apr-86 1943 JAR@MC.LCS.MIT.EDU Immutable code and quoted data
C02329 00523 ∂04-Apr-86 1943 JAR@MC.LCS.MIT.EDU Immutable code and quoted data
C02331 00524 ∂06-Apr-86 2037 @MC.LCS.MIT.EDU:wagle%indiana.csnet@CSNET-RELAY.ARPA LETREC (REC)
C02334 00525 ∂07-Apr-86 0858 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: expansion of LETREC
C02336 00526 ∂07-Apr-86 0901 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: expansion of LETREC (hmmm)
C02340 00527 ∂07-Apr-86 0906 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: Immutable code and quoted data
C02343 00528 ∂07-Apr-86 0908 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA efficiency vs functionality
C02346 00529 ∂07-Apr-86 1338 @MC.LCS.MIT.EDU:GJS%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Re: expansion of LETREC (hmmm)
C02349 00530 ∂07-Apr-86 1343 @MC.LCS.MIT.EDU:GJS%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Re: Immutable code and quoted data
C02351 00531 ∂07-Apr-86 1910 @MC.LCS.MIT.EDU:DAVID%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU expansion of LETREC (hmmm)
C02355 00532 ∂07-Apr-86 1927 @MC.LCS.MIT.EDU:DAVID%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
C02357 00533 ∂08-Apr-86 0713 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: expansion of LETREC (hmmm)
C02360 00534 ∂08-Apr-86 1609 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Where'd all that mail come from??!!
C02366 00535 ∂08-Apr-86 1806 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@mc.lcs.mit.edu Where'd all that mail come from??!!
C02371 00536 ∂08-Apr-86 2153 JAR@MC.LCS.MIT.EDU expansion of LETREC
C02374 00537 ∂09-Apr-86 0113 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA meaning of *global* define
C02379 00538 ∂09-Apr-86 0627 @MC.LCS.MIT.EDU:JMILLER@OZ.AI.MIT.EDU Re: meaning of *global* define
C02381 00539 ∂09-Apr-86 0820 @MC.LCS.MIT.EDU:GJS%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Re: meaning of *global* define
C02386 00540 ∂09-Apr-86 1026 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@mc.lcs.mit.edu meaning of *global* define
C02391 00541 ∂09-Apr-86 1250 @MC.LCS.MIT.EDU:cth%indiana.csnet@.ARPA delayed replies
C02396 00542 ∂09-Apr-86 1320 @MC.LCS.MIT.EDU:cth%indiana.csnet@.ARPA Use at Indiana University
C02402 00543 ∂09-Apr-86 1759 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: Where'd all that mail come from??!!
C02405 00544 ∂10-Apr-86 0554 @MC.LCS.MIT.EDU:adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA LET from LET* ?
C02408 00545 ∂10-Apr-86 0554 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA arg lists to APPLY
C02412 00546 ∂10-Apr-86 0836 @MC.LCS.MIT.EDU:gls@aquinas.think.com Where'd all that mail come from??!!
C02416 00547 ∂10-Apr-86 1047 JAR@MC.LCS.MIT.EDU Where'd all that mail come from??!!
C02420 00548 ∂10-Apr-86 1628 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA CS5PA Summer Session
C02422 00549 ∂11-Apr-86 0719 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA early binding
C02426 00550 ∂11-Apr-86 1054 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@mc.lcs.mit.edu early binding
C02429 00551 ∂11-Apr-86 1459 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@mc.lcs.mit.edu early binding
C02434 00552 ∂11-Apr-86 1554 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: meaning of *global* define
C02438 00553 ∂11-Apr-86 1722 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@mc.lcs.mit.edu early binding
C02440 00554 ∂11-Apr-86 1726 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: early binding
C02448 00555 ∂11-Apr-86 1826 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@mc.lcs.mit.edu early binding (150 lines)
C02461 00556 ∂12-Apr-86 0101 @MC.LCS.MIT.EDU:rkirchne%carleton.csnet@CSNET-RELAY.ARPA The generality of define
C02463 00557 ∂12-Apr-86 0810 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU The generality of define
C02465 00558 ∂12-Apr-86 0830 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@mc.lcs.mit.edu early binding (150 lines)
C02470 00559 ∂12-Apr-86 1434 @MC.LCS.MIT.EDU:KMP@SCRC-STONY-BROOK.ARPA (DEFINE (((...) ...) ...) ...)
C02473 00560 ∂12-Apr-86 1453 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@mc.lcs.mit.edu meaning of *global* define
C02480 00561 ∂13-Apr-86 2255 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@mc.lcs.mit.edu early binding (150 lines)
C02484 00562 ∂14-Apr-86 0131 @MC.LCS.MIT.EDU:rkirchne%carleton.csnet@CSNET-RELAY.ARPA define
C02486 00563 ∂14-Apr-86 1337 JAR@MC.LCS.MIT.EDU define
C02489 00564 ∂14-Apr-86 1526 JAR@MC.LCS.MIT.EDU meaning of *global* define
C02493 00565 ∂14-Apr-86 1534 JAR@MC.LCS.MIT.EDU early binding
C02498 00566 ∂14-Apr-86 1549 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU meaning of *global* define
C02501 00567 ∂14-Apr-86 1625 @MC.LCS.MIT.EDU,@XX.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: meaning of *global* define
C02505 00568 ∂15-Apr-86 1514 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: early binding
C02510 00569 ∂15-Apr-86 1624 @MC.LCS.MIT.EDU,@XX.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: meaning of *global* define
C02513 00570 ∂16-Apr-86 1808 JAR@MC.LCS.MIT.EDU early binding
C02518 00571 ∂17-Apr-86 0909 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: early binding
C02522 00572 ∂17-Apr-86 1241 JAR@MC.LCS.MIT.EDU early binding
C02525 00573 ∂23-Apr-86 1609 andy@aids-unix(AndyCromarty)@MC.LCS.MIT.EDU Re: The generality of define
C02529 00574 ∂23-Apr-86 2013 JAR@MC.LCS.MIT.EDU variata
C02536 00575 ∂25-Apr-86 0406 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: variata
C02544 00576 ∂25-Apr-86 1356 JAR@MC.LCS.MIT.EDU variata
C02562 00577 ∂25-Apr-86 1537 @MC.LCS.MIT.EDU:andy@aids-unix Re: variata
C02566 00578 ∂25-Apr-86 1804 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: variata
C02577 ENDMK
C⊗;
∂29-Nov-84 1009 RPG Comments on the Preliminary Report (2 pages)
∂28-Nov-84 0331 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Comments on the Preliminary Report (2 pages)
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Nov 84 03:31:05 PST
Received: from unc by csnet-relay.csnet id a021839; 28 Nov 84 6:30 EST
Received: by unc (4.12/4.7) id AA17493; Tue, 27 Nov 84 23:00:58 est
Date: Tue, 27 Nov 84 23:00:58 est
From: Kent Dybvig <dyb%unc.csnet@csnet-relay.arpa>
Message-Id: <8411280400.AA17493@unc>
To: scheme@mit-mc.ARPA
Subject: Comments on the Preliminary Report (2 pages)
Cc: willc%indiana.csnet@csnet-relay.arpa
Comments on Essential Scheme
These comments are arranged in four categories: lambda syntax, other
special forms, functions, and lexical matters. I feel quite strongly
about the issues I outline here. I have other minor gripes (don't we
all) that I didn't bother to include here, for fear they would water
down the substantive issues.
Lambda Syntax
For several years my Scheme system has had a syntax for lambda
expressions that allows naming of the closure within the body of the
closure for enhanced readability and efficiency. The syntax is:
(lambda name formals . body)
where name is a symbol bound lexically to the closure within body,
formals is a list of formal parameters, and body is a set of zero or
more forms to execute. Name may be omitted and there is no ambiguity
since formals is always a list.
This feature, which I have called "named lambda," allows terse,
referentially transparent recursive function definitions. It is similar
to the optional "rec," special form, but is shorter and perhaps more
easily optimized than rec. It is quite a bit shorter than using
"letrec." For example, the boring factorial function looks like:
(lambda fact (x) (if (= x 0) 1 (* x (fact (- x 1))))),
a totally self contained definition.
Named lambda generalizes to named let, something which seems to have
appeared elsewhere independently. It looks like:
(let name ((x1 v1) (x2 v2) ...) . body),
where name may again be omitted. It translates into:
((lambda name (x1 x2 ...) . body) v1 v2 ...),
and replaces the old iterate expression.
Unfortunately, the partial destructuring provided by the adopted lambda
syntax conflicts with the named lambda syntax, introducing an ambiguity
in some cases, as in:
(lambda f (g x) ...).
Is this a named lambda with two formals or an unnamed lambda with a
single &rest formal?
The partial destructuring syntax is merely a different syntax for the
&rest formal parameter adopted by Common Lisp. The only benefit to be
gained by not using the Common Lisp syntax is that some implementations
might generalize to full destructuring. I think it more likely that we
would want to generalize to optional arguments. Why not just use part
of the syntax adopted by Common Lisp? For now, we could make the &rest
syntax required and the &optional syntax optional.
If everyone dislikes the &rest syntax then I think we ought to resolve
the ambiguity with named lambda by requiring the name to be present.
This would improve code readability and facilitate optimization
regardless of the system the code is executed on.
Other Special Forms
1. The "if" special form should require an else part. This allows the
compiler/interpreter to make a sanity check for the user which might
save some grief, and seems a little cleaner. The macros "when" and
"unless" are the appropriate way to express the intended meaning.
2. Block is a much better name for the statement grouping special form
than "begin". Do we really need an artifact of Algol syntax in our
language? After all, it is a block of code, not a begin of code.
(If someone is worried about clashing with a process blocking function
they should name their function "block-process.")
3. Case expressions should allow single keys without putting them in a
list. The user rarely wants the single key to be a list (eq semantics
and all), so there really isn't any ambiguity. Since single keys are
probably the most common, case expressions will be less bulky.
For example,
(case x ((a) ...) ((b) ...) ((c d) ...) (else ...))
would simply be
(case x (a ...) (b ...) ((c d) ...) (else ...)).
Functions
1. Call/cc should be an alternative to call-with-current-continuation.
How are we ever going to get people to feel comfortable with something
so imposing that it requires 30 keystrokes to type in and takes up half
a line?
2. Transcendental functions should be required only in implementations
with floating point numbers, not just any implementation with numbers
other than integers. In particular, an implementation with rational or
interval arithmetic should not be bound to supporting transcendental
functions. (This was probably just a misstatement in Will's note.)
3. The length function should be generic, returning a value for all
reasonable arguments. There can still be individual functions list-
length, string-length, vector-length, and so on.
Lexical Matters
Scheme systems should be case sensitive. Let's not forget that symbols
have other uses than as Scheme identifiers. How can we implement
prolog-like variables in Scheme without being able to differentiate
between upper and lower case letters within the symbols? Does anyone
really still use an upper-case only terminal? Assuming case
sensitivity, all standard Scheme functions and special forms should be
written with entirely lower-case letters.
∂30-Nov-84 1658 RPG Re: Kent Dybvig's Comments on Scheme
∂30-Nov-84 1545 @MIT-MC:bartley%ti-csl.csnet@csnet-relay.arpa Re: Kent Dybvig's Comments on Scheme
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 30 Nov 84 15:44:40 PST
Received: from ti-csl by csnet-relay.csnet id a008334; 30 Nov 84 18:12 EST
Date: 30 Nov 1984 1147-CST
From: David Bartley <Bartley%ti-csl.csnet@csnet-relay.arpa>
Subject: Re: Kent Dybvig's Comments on Scheme
To: Scheme@mit-mc.ARPA
cc: Bartley%ti-csl.csnet@csnet-relay.arpa
Re: Kent Dybvig's comments on the preliminary report on Scheme
I'd like to briefly add my "votes" on Kent's suggestions and bring up
some additional complexities in the issues he raised.
Lambda Syntax
I prefer (REC name (LAMBDA args . body)) first, then MIT-style
NAMED-LAMBDA second. (I support both.) Will's discussion summarizes
my reasons quite well. We should NOT require all lambdas to be named.
IF without else part
I would not mind requiring WHEN in this case, making (IF a b)
syntactically incorrect. This allows better compile-time checking. I
use WHEN myself to make this distinction and find it useful. BTW, I do
NOT find UNLESS useful, since (WHEN (NOT ..)..) usually reads better.
BLOCK vs BEGIN vs LET()
As Will points out, the real question is whether the construct we have
in mind is a compound expression or an Algol-like block containing both
declarations and expressions to be evaluated. I prefer BEGIN for the
former and LET for the latter.
The problem is that Will suggests (paraphrasing someone else) that
(BEGIN ...) might be equivalent to (LET () ...). I have conflicting
thoughts on this. Pro: if they are the same, then I would vote to
remove BEGIN from the (essential) language as hopelessly redundant with
LET. Con: early papers by Steele and Sussman treat (BEGIN a b) as a
macro for ((LAMBDA (ignored-id) b) a), which is equivalent to
(LET ((ignored-id a)) b). Thus, BEGIN already is a scope-extending
operation.
This has the following practical consequence. What is the scope of FOO
in the following?
(define (f ...)
(define g ...)
(begin
(define foo ...))
body)
I understand that MIT Scheme "promotes" both G and FOO directly under
F. This hack is needed for macros that expand into multiple DEFINEs
and thus must be "wrapped" in something to be spliced in correctly.
If we define BEGIN in terms of LET, then the scope of FOO will have to
be confined to the scope of the BEGIN.
What should we do? I vote that BEGIN indicate a compound expression,
contrary to early Steele&Sussman, and that LET() be used for
Algol-style blocks.
CASE expressions with single keys
We will accept single keys in CASE expressions. If ELSE is to be a
single key in the last clause, however, it will have to be enclosed in
parentheses to avoid being interpreted as "otherwise".
CALL/CC
"CALL-WITH-CURRENT-CONTINUATION" is nonsense to the unititiated, too.
I will support both, but feel like it's silly to have the long name.
Must this be a procedure (e.g. a potential funarg) or can we treat it
as a special form?
Transcendental functions
What's the problem? Just call them "optional" as a group. What we've
been arguing is whether I have "true Scheme" if I have some kind of
representation for "real numbers" but don't support a certain set of
functions. This is irrational!! (sorry)
Generic LENGTH
I strongly abhor Common LISP-style genericity. As Will says, "generic"
operations on numbers with multiple REPRESENTATIONS is one thing, but
trying to be generic across different kinds of things is something
else.
Case-sensitive symbols
I feel very strongly that symbols, as processed by the reader, should
NOT be case sensitive and that (EQ? 'a 'A) be true. STRING->SYMBOL
should preserve case, however, and (EQ? '|a| '|A|) should be false.
-- David Bartley (Bartley @ TI-CSL)
-------
∂01-Dec-84 1049 RPG Kent Dybvig's Comments on Scheme
∂30-Nov-84 2036 @MIT-MC:JINX@MIT-OZ Kent Dybvig's Comments on Scheme
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 30 Nov 84 20:35:53 PST
Date: 30 Nov 1984 23:35 EST (Fri)
Message-ID: <JINX.12067849164.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Cc: Scheme@MIT-MC.ARPA
Subject: Kent Dybvig's Comments on Scheme
In-reply-to: Msg of 30 Nov 1984 12:47-EST from David Bartley <Bartley%ti-csl.csnet at csnet-relay.arpa>
BEGIN should certainly not add another contour. BEGIN is
equivalent to LET() if environments are not first class, but they are
in MIT Scheme. An incremental definition to the environment where the
subexpressions of the BEGIN expression are evaluated would have
different effects depending on whether a new contour was created or
not. I agree that BEGIN (for lack of a better name) should indicate a
compound expression and LET should be used for blocks.
Note that this is not contrary to all early Scheme papers
since in the Revised Report,
(BLOCK X Y) = ((LAMBDA (A B) (B)) X (LAMBDA () Y)).
X is evaluated in the environment where the BEGIN
expression appears, and Y is evaluated in an environment where no
bindings have been added. In a dialect without first-class
environments and without internal definitions, the environment where Y
is evaluated is the same as that where X is evaluated, thus no
contours have been added.
I think that there are only two valid reasons for adding
special forms:
- They provide a convenient syntax for something which
could be expressed only considerably more clumsily without them.
Example: COND (as compared to nested IFs). These are usually macros
which expand into the clumsier form.
- They provide an extension to the language which requires
special handling by the interpreter or compiler. Their effect could
otherwise not be achieved. Example: QUOTE. These are the "TRUE"
special forms.
I don't think that CALL-WITH-CURRENT-CONTINUATION falls in
either class, so there is no need to make it a special form. Besides,
a portable program would not be able to rename it since we have not
specified a way for adding syntactic extensions.
Allowing IF not to have an alternative sub-expression is
convenient because it is clear and eliminates the need for WHEN,
another special form. I don't like the proliferation of special forms
and would object strongly to requiring another one for this purpose.
I can't see that there is a difference between WHEN and IF in terms of
compile-time checking. IF with two subexpressions and IF with three
subexpressions can be treated as different beasts.
I agree with the remaining three points.
- Bill Rozas (JINX@MIT-MC)
∂05-Dec-84 1353 RPG Re: Kent Dybvig's Comments on Scheme
∂04-Dec-84 2015 @MIT-MC:HUDAK@YALE.ARPA Re: Kent Dybvig's Comments on Scheme
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 4 Dec 84 20:15:10 PST
Received: by YALE-BULLDOG.YALE.ARPA; 4 Dec 84 11:49:28 EST (Tue)
Message-Id: <8412041649.AA04845@YALE-BULLDOG.YALE.ARPA>
Received: from YALE-RING by YALE-RES via CHAOS; Tue, 4 Dec 84 11:37:43 EST
Subject: Re: Kent Dybvig's Comments on Scheme
Date: Tue, 4 Dec 84 11:37:46 EST
From: Paul Hudak <Hudak@YALE.ARPA>
To: Bill Rozas <JINX%MIT-OZ@MIT-MC>
Cc: Scheme@MIT-MC, Hudak@YALE.ARPA
In-Reply-To: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>, 30 Nov 1984 23:35 EST (Fri)
Not having participated in the workshop, I've been hesistant about
making comments on the various issues flying by recently, but I couldn't
resist responding to Bill Roza's comments on special forms:
I think that there are only two valid reasons for adding
special forms:
- They provide a convenient syntax for something which
could be expressed only considerably more clumsily without them.
Example: COND (as compared to nested IFs). These are usually macros
which expand into the clumsier form.
- They provide an extension to the language which requires
special handling by the interpreter or compiler. Their effect could
otherwise not be achieved. Example: QUOTE. These are the "TRUE"
special forms.
I think there's one other reason, which in a sense subsumes the first:
*readability*. In particular, with regard to IF having or not having
an alternative sub-expression, I find that when I'm reading code and
come across an IF expression, I look very hard to see if it has an
alternative branch. If it doesn't, I look again to be sure I didn't
miss it. I think this "convenient feature" degrades readability.
I agree with Bill Rozas that one shouldn't proliferate special forms,
but my reason is that they are typically complex, and their syntax
becomes hard to remember. However you can't get much simpler than
WHEN and UNLESS. Their use, in my opinion, greatly enhances
readability.
- Paul Hudak (hudak@yale)
∂07-Dec-84 1341 RPG [willc: preliminary report of workshop]
∂06-Dec-84 1909 KMP@MIT-MC [willc: preliminary report of workshop]
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 6 Dec 84 19:09:23 PST
Date: 6 December 1984 22:02-EST
From: Kent M Pitman <KMP @ MIT-MC>
Subject: [willc: preliminary report of workshop]
To: willc%indiana.csnet @ CSNET-RELAY
cc: SCHEME @ MIT-MC
In-Reply-To: <8411120256.AA05811@iuvax.UUCP>
Ok, Will, I'm assuming things decided at the meeting are not cast in
concrete. I certainly take issue with a number of the decisions.
In a few places, I also pick on your notation a bit when I think
its unclear. Thanks for taking the time to write up everything.
Here come the comments...
* I dislike the description of "optional features". In particular,
you say:
Optional features may not be supported by every implementation,
but those that do support a feature will use the same syntax and
semantics for the feature. Hence code that makes use of optional
features will run on any implementation of Scheme that supplies
the optional features.
....
An implementation may extend the language in any way whatsoever,
but code that makes use of extended features is not portable.
These two paragraphs are in conflict and allow for lots of
inconsistency which I will identify at appropriate points later.
The principle troubles, though, are:
* Since a language can be extended in "any way whatsoever",
can such extensions be syntactically in conflict with optional
language features? eg, if #\ is optional and my dialect doesn't
use it, can I then define my own #\ as an extended part of the
required subset?
* In some cases, "required" language features can be redefined
incompatibly by "optional" features. eg,
(COND (FOO => X))
has a well-defined semantics regardless of whether the optional
"=>" feature of COND is present. However, that semantics is not
the same in the two cases.
The point I'm trying to make is that saying something is "optional" says
little if anything unless you at least define that if anyone uses the
syntax corresponding to the optionality in a dialect which doesn't support
the feature, that he is in error. Put another way, extensions may not
invalidate optional features. On the other hand, if this were stipulated
the list of "optional" features to which I objected would be quite lengthy.
* I disagree with calling the string quote character "double quote".
I prefer "doublequote". Since there is a character named "quote", the
phrase "double quote" might designate '' instead of ".
* In discussing what terminates tokens, you should say which of these
characters (presumably all) are also single-character tokens. In
particular, that "((A B)C)" is tokenized
{"(" "(A" " " "B" ")C" ")"}
or {"(" "(" "A" " " "B" ")" "C" ")"}
hangs in the balance. I'm sure no one disagrees, but if you're not going
to be complete about these things, you are sort of wasting your time
just trying to look formal about things.
* I agree with reserving {, [, ], and }, but I would specify that they
may be used as alphabetic according to syntactic escape conventions.
Optionally, the following characters may be delimiters that
terminate symbols:
* What does it mean to say single quote, backquote and sharpsign
may "optionally" terminate tokens? It means expressions
like (JOHN'S COAT) read differently in the different dialects. How
is this distinct from saying "Optionally, the following characters
may be delimiters that do not terminate symbols:"? It only makes
sense to say something is optional if it's going to mean that when
it's present. I bet some dialects treat (JOHN'S COAT) as a two-list
and others treat it as a three-list. Hence, any description of this
relation between dialects can at best say: "The specification takes
no stand on the issue of whether the following delimiters terminate
symbols. Any use of expressions like (JOHN'S COAT) are to be considered
non-portable."
* I would personally prefer if vertical bar had been defined to be
alphabetic, but I am at least happy that it is "not specified" what
its meaning is rather than that it is "optional".
* I strongly oppose the idea of not specifying an escape char for
symbols. You say there is "widespread agreement that ``slashification''
of characters within symbols is a relic that ought to be abandoned."
I am not party to such agreement.
I strongly oppose the idea of eliminating slashification. The Maclisp
conventions of vertical bars made up for the absence of strings. With
their passing, syntactic quoting of lots of chars is very rare, and
in those few cases, I think slashing works fine. It also is a low-cost
mechanism for the printer, since no lookahead is required. Also, it is
uniform with respect to strings, which already use slash for special
chars anyway. Finally, without slash, there would be no way to get
vbars into symbol names, since vbars cannot adequately quote themselves.
On the other hand, slash can work fine in the absence of vbar. So if
one thing is to go as a readsyntax quoter, it should be vbar.
* Will-- Your meta-syntactic use of "..." in a description of what
the "." character does is very confusing.
* Does anyone mind if (. A) is the same as A? It has a certain elegance
to it if you think about it.
(CONS 3 (CONS 2 (CONS 1 0))) => (3 . (2 . (1 . 0))) => (3 2 1 . 0)
(CONS 2 (CONS 1 0)) => (2 . (1 . 0)) => ( 2 1 . 0)
(CONS 1 0) => (1 . 0) => ( 1 . 0)
0 => 0 => ( . 0)
Just a thought.
* I find #!true and #!false to be ugly and visually confusing
with the popular convention of "!" designating something
destructive. It would make more sense for #! to be saved for
something like #. in Common Lisp. I agree #<something>TRUE
is reasonable. I'd have preferred #: for this.
* What does it mean to say:
"Optionally, binary numbers may be written using the #b notation.
Optionally, octal numbers may be written using the #o notation.
Optionally, decimal numbers may be written using the #d notation.
Optionally, hexadecimal numbers may be written using the #x notation."
Presumably this means that dialects not wanting #B, #O, etc. can
use these to mean other things.
* What does it mean to say:
"Optionally, special characters may be written using the #\
notation. If this feature is supported, then the Common Lisp
names for special characters must be supported."
Presumably this means that if I don't want to be able to write special
characters, I can make #\ do something else. In fact, if I want to
use other names than those used by Common Lisp, I can just "not support"
this feature and then "make any extension whatsoever" to my dialect
such that #\ does something completely different, like understand
a different set of character names.
* Was anything decided about whether #!TRUE and #!FALSE would self-evaluate
or whether they required quoting?
* Was anything decided about whether numbers must self-evaluate or
whether a dialect may require quoting?
* Since "optionally, numbers may be written using decimal points and/or
exponents", does this mean that numbers with decimal points are integers
or floating? Does it mean that if I don't support the feature that
I can take the alternate position?
* I notice that the space of symbol names is highly constrained for
the "required subset". A property, however, that should be required
is that within any given dialect, every interned symbol (no matter what
characters it contains) must have a printed representation which is
read-invertable within that dialect. I suspect that all dialects
do this already anyway, but it should be a guaranteed property of the
language since programmers will tend to depend on such things and should
have a guaranteed semantics backing them up.
* What does it mean to make NIL optionally evaluate to the empty list
or optionally evaluate to false. What happens if I make it false and
then try to run my code in another dialect where it's the empty list
and where the two are not the same thing. The definition of optionality
says that code written in the optional subset will run correctly in
another dialect supporting optional features. It doesn't seem to me
like a good idea to optionally define a symbol as able to take on several
values and then be able to write meaningful code.
* It is specified that "the order of evaluation within an application
is not specified". I would prefer "combination" or "expression" to
"application" as a matter of terminology to avoid confusion with the
application that happens in the APPLY function, which doesn't involve
evaluation at all.
* I don't like the name LETREC; I preferred LABELS. Neither is very
suggestive of anything; the latter is at least a real word.
* Will-- I don't like the use of the term "mistake" throughout the report,
at least without defining it formally. In my dialect, it connotes
an unintentional error and it seems to me that if the user
intentionally did the offending thing, it would not be a mistake.
I would say "error" in its place, or define the term "mistake"
formally early on.
* I disagree with the various forms that claim it to be a "mistake"
to use certain return values, allowing some implementations to
signal an error. I don't agree that such errors can ever be
detected at the language level; I would like a formal description
of exactly when it is believed that such an error could be signalled.
The forms in question are: IF, COND, SET!, DEFINE, DEFINE!, CASE,
SET-CAR!, SET-CDR!, and VECTOR-SET!.
* The semantics of (COND (X => Y)) is messy due to optionality as
described earlier.
* Will-- I would name the ... sequences in definitions of things
like LET, COND, etc which use multiple sequences. I realize you
use them right to left, but that could be made more apparent.
Perhaps ..foo.. instead of ...
* I find the name SET! both ugly and redundant. The "!" convention
as originally created by the T people identifies a destructive
variant of an otherwise-non-side-effecting operation. So, for
example, APPEND and APPEND!, etc. Logically, there could be a
CHANGE-CAR and CHANGE-CAR!, one of which was
(LAMBDA (C V) (CONS V (CDR C)))
and the other which was
(LAMBDA (C V) (SET (CAR C) V) C)
In any case, I strongly think that the primitive for assigment
should be SET and not SET!. In fact, since no one likes assignment
anyway, I don't see any reason why anyone should object to just
leaving this undefined in the standard. It would only discourage
people from writing destructive code. But I would be very unhappy
to see T change the name of SET to SET!. Similarly, I strongly
dislike the name SET-CAR! and SET-CDR!.
* The definition of DEFINE refers to the "top-level" definition of
a variable. I don't believe it's established what "top-level" means,
so this definition is pretty muddy. Further, what is the implication
of this definition upon doing (LAMBDA (X) (DEFINE X X))?
I am very discouraged that the (DEFINE (fn . args) ...) syntax isn't
required. This means that any portable code must be ugly, meaning
no one is likely to ever write truly portable code, meaning this
standard is a farce.
* It is silly to require that there be at least one form in a (BEGIN).
It is easy for macros to come up with situations where there are
no forms to put there and as long as the macro's caller doesn't
depend on the value, it shouldn't matter. The return value of a
BEGIN with no forms should just be undefined.
* The fact that (LET* ...) cannot admit an optional name reveals an
asymmetry which I find very distasteful. I suggest that named LET
be left to implementors as an "arbitrary" extension not to be mentioned
in any common subset.
* I would prefer to have REC be called LABEL. Again, at least it's English.
* I don't see any good reason to have DO not bind RETURN. Can someone
elaborate on that?
* The description of DEFINE inside LAMBDA is inconsistent with the
earlier description of DEFINE as creating a toplevel definition.
I think this should be a non-standard extension. I see no reason to
dignify it with any "optional" status.
* The term "top-level binding" is again completely vague in DEFINE!'s
definition.
* The definition of optionality specified that if an optional feature
was present, the dialect should prefer to call it by the "optional"
name. This is somewhat inconsistent with making SEQUENCE an optional
synonym for BEGIN. Since it is not encouraged for use and is not going
to exist in all dialects, is there any sense to including it here?
* The entire section on datatypes is hopelessly muddled. About the only
useful thing said is that anything which is a first class object must
have unlimited extent.
* In the sentence "There is an object which represents both false and
the empty list", I cannot discern whether that means there may/must
be one/two objects filling that description. Shouldn't we say,
"False and the empty list must be represented as first class objects
and that object {may,must} [not] be distinct." or some such.
* Since datatypes are not declared to be disjoint, it isn't necessary
to mention that characters may be represented as numbers, except perhaps
as a footnote to remind the forgetful reader. Strings can be represented
as numbers, too, the way things are written.
* Was there really anyone who thought streams shouldn't be first class
objects? Since datatypes aren't disjoint and such objects could be
indistinguishable from numbers or arrays or whatever, is there really
a reason to care?
* The unary procedure not should be defined to return "a true value if
its argument is false and a false value if its argument is not false."
... rather than "if its argument is true." for the second part.
* I suggest renaming CALL-WITH-CURRENT-CONTINUATION (or CALL/CC) to just
CONTINUE. eg,
(CONTINUE (LAMBDA (C) (IF (FOO) (F C) (G C))))
Anyone else support this?
* By the way, saying the escape procedure has unlimited extent doesn't say
it can be called more than once. Does everyone agree to either stipulate
that or not?
* If "the unary predicate NUMBER? is true of numbers and false of
everything else" and "the unary predicate INTEGER? is true of
integers and false of everything else", I don't suppose this says
much since types are not disjoint and so strings are not necessarily
not numbers and need not necessarily cause INTEGER? or NUMBER? to
return false. Certainly characters needn't yield false from NUMBER?
or probably from INTEGER?. As such, these predicates are of limited
value.
* Of what point is it to make claims about what "almost all implementations"
will do for real numbers? Either they're required to or they aren't.
The rest belongs in some other document.
* I don't agree that allowing generalization of +, -, *, and / to arbitrary
arity is a good idea or even well-defined. eg, the proper generalization
of - to arity 1 is (- 3) => 3, not (- 3) => -3. Hence, specifying that unary
negation is optional is in conflict with specifying that - may be generalized.
* Will-- The discussion of QUOTIENT/REMAINDER and of CONS/CAR/CDR should
use the word "respectively" in the appropriate places. When I first read
that QUOTIENT and REMAINDER return the quotient and remainder, I spent
an unduly long time flipping back pages looking to see if you'd allowed
multiple values before I realized that it was silly for both these functions
to do the same thing or for that same thing to be what it had first looked
to me like they're doing.
* I don't see why MIN/MAX should be restricted from arity 0. They should
just return the smallest and largest representable numbers. I guess as
long as they aren't defined to signal an error in this case, individual
dialects could be extended anyway.
* It should be made explicit whether (= 1 1.0) is defined to work. Note that
this may be tricky since even (= 1.0 1.0) won't necessarily work if the
1.0's were computed rather than read and have different bit patterns that
are too tiny to make a difference on output.
* It is silly to specify that implementations may "optionally" support
numbers that are non-integers. Why not just define that (NUMBER? x)
doesn't imply (INTEGER? x). That definition wouldn't mean that
every number wasn't an integer, it would only mean that every number
wasn't necessarily a number.
Specifying that "almost all implementations" will support this option
is again silly and might in pathological situations be misleading.
* Is the definition of (TRUNCATE x) really correct? It looks like it must
be screwed up on the negative side near 0. eg, (TRUNCATE -0.5) doesn't
have the same sign as 0.5 does it? Or is there a negative 0?
* The meaning of "interning" a symbol should be specified.
* It should be stated explicitly that CAR and CDR of the empty list
is not defined.
* What's this nonsense about pairs being maybe indistinguishable from
vectors of length 2. Is there a good reason for that? It doesn't really
matter since numbers haven't been defined as distinguishable from
strings either, but it somehow offends my sense of aesthetics to see
this note here. Is this due to some problem with Maclisp HUNK2's or
something unrelated?
* In "The following descriptions use the notion of a proper list. The
set of proper lists is the smallest set satisfying:
the empty list is a proper list
a pair x whose CDR is a proper list is a proper list,
provided (MEMQ x (CDR x)) is false."
I think MEMQ isn't the function that you want, but I find it amusing
to see the language defined meta-circularly in this way (since MEMQ
is almost certainly defined to terminate only on proper lists and may
even want to type-check proper-list-ness).
* Is the function LENGTH defined to err or to not return when given
a circular list? What about an otherwise improper (ie, dotted) list?
* The definition of APPEND is poor. It should be defined with NAMED-LAMBDA
for safety in situations where APPEND gets redefined. Also, its text
description is too windy.
* I see no reason for APPEND! to be defined to possibly side-effect
either arg. This may force lots of needless copying in order to write
provably correct programs. I can't imagine a definition of APPEND!
which would want to destructively modify its last argument.
* All these definitions (APPEND, REVERSE, ...) are ugly due to the
silly restrictive version of DEFINE. I certainly wouldn't want my
students programming like that.
* It should be stated in English what happens if LIST-REF and LIST-TAIL
fall off the end. I assume it follows from the definitions of CAR/CDR
that such is a signallable error.
* There should be MEMQ?, MEMV?, and MEMBER? to match MEMQ, MEMV, and
MEMBER. This enhances garbage collection since if these functions
are only being used for truth value, you don't want to hold pointers
to potentially large list structures. Also, it enhances debugging since
if F is a function on booleans, (F (MEMQ X Y)) will receive true/false
rather than a list or false. Ditto for ASSQ?, ASSV?, and ASSOC?.
* You specify no order of evaluation for MAPCAR. I think you mean no
order of "application".
* I dislike the asymmetry between MAPCAR and MAPC.
MAPC has no defined return value, MAPCAR does.
MAPC has defined order of application, MAPCAR does not.
In short, they have nothing really in common other than they type
of their args. I think they should not be named so similarly.
* I oppose the names MAPCAR and MAPC.
T calls these MAP and WALK, respectively.
The generic form of MAPCAR, which is the only thing for which
arbitrary order of application would make sense (since lists are
only sequentially accessible anyway), has no business being called
MAPCAR.
* With respect to the questions about VECTOR->LIST, I think the
right thing to say is that the conses it returns are mutable,
not that the result is necessarily a "new object", since if the
result is the empty list (eg, from an empty vector), I wouldn't
want the implication to be that
(NOT (EQ (VECTOR->LIST #()) (VECTOR->LIST #())))
since it follows from that that more than one false value must
(rather than "may") be possible.
* What happens if VECTOR-REF is out of range?
* VECTOR-SET! is ugly. It should at least be called SET-VECTOR-REF!
for symmetry with the other SET- things. Personally, I hate the
! and would strongly prefer just SET-VECTOR-REF.
* The relation between OBJECT-HASH and the GC should be specified.
Do things get GC'd if no other pointers exist to them? Also, it
might help to distinguish this kind of "hash" from the number that
comes from SXHASH in Maclisp. It took me a second to realize you
weren't talking about that.
------- End undelivered message -------
------- End undelivered message -------
∂07-Dec-84 1342 RPG Slashification
∂07-Dec-84 1327 JAR@MIT-MC Slashification
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 7 Dec 84 13:27:00 PST
Date: 7 December 1984 16:26-EST
From: Jonathan A Rees <JAR @ MIT-MC>
Subject: Slashification
To: KMP @ MIT-MC
cc: SCHEME @ MIT-MC
In-reply-to: Msg of 6 Dec 1984 22:02-EST from Kent M Pitman <KMP>
I think I was the one who suggested that there be neither slashification
nor vertical barring. If you tell the T printer not to use either \ or
| and it comes across a symbol which requires quoting anyhow, it prints
#[Symbol "foo"]. (If you have \ but not |, as in T, you need to have a
way to print the null symbol anyhow; it really does come out as #[Symbol
""] - try it.) If print tables exist or if STRING->SYMBOL accepts any
string whatsoever, then it is necessary to have some way for unusual
symbols to read and print, but there's not really any need to wire down
a special character for the purpose, because e.g. some # syntax could be
used.
Some people wanted to throw away \ in favor of just | ; people didn't
agree when I suggested going with \ but not | ; so we just decided that
the need was unimportant enough that neither syntax was required. I'm
not convinced that there needs to be a defined, portable way to print
unusual symbols, although maybe you could talk me into such a position.
Jonathan
∂09-Dec-84 1252 RPG MIN/MAX, DO/RETURN
∂08-Dec-84 1556 KMP@MIT-MC MIN/MAX, DO/RETURN
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 8 Dec 84 15:56:47 PST
Date: 8 December 1984 18:55-EST
From: Kent M Pitman <KMP @ MIT-MC>
Subject: MIN/MAX, DO/RETURN
To: SCHEME @ MIT-MC
References: Msg of 6 Dec 1984 22:02-EST from Kent M Pitman <KMP@MIT-MC.ARPA>
Jonathan Rees had a good points about a couple of my earlier remarks...
* Making MIN/MAX return smallest/largest representable number would
be infeasible in implementions with bigfloats or bignums. I should
have thought of that. (I must have been thinking too hard about
the flonum case; sorry.) I'll withdraw that suggestion.
* Making DO bind RETURN would have been a bad idea since it would "wire"
the name RETURN. I withdraw my disparaging remarks about its not binding
that name.
-kmp
∂09-Dec-84 1304 RPG Re: critique of preliminary report
∂09-Dec-84 1142 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa Re: critique of preliminary report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 9 Dec 84 11:42:25 PST
Received: from indiana by csnet-relay.csnet id a022287; 9 Dec 84 14:34 EST
Received: by iuvax.UUCP (4.12/4.7)
id AA06716; Sat, 8 Dec 84 22:50:32 est
Date: Sat, 8 Dec 84 22:50:32 est
From: Will Clinger <willc%indiana.csnet@csnet-relay.arpa>
To: KMP@mit-mc.ARPA
Subject: Re: critique of preliminary report
Cc: scheme@mit-mc.ARPA
I am posting this in response to Kent Pitman's excellent critique
of the preliminary report on the October workshop.
ERRORS AND OVERSIGHTS
I should have said:
Numbers, strings, characters, and #!TRUE and #!FALSE are
self-evaluating, which means they need not be quoted. Symbols and
pairs are not self-evaluating. It is not specified whether other
things are self-evaluating.
The semantics of (BEGIN) is not specified.
TRUNCATE could be defined by
(DEFINE TRUNCATE
(LAMBDA (X)
(IF (NEGATIVE? X)
(- 0 (FLOOR (ABS X)))
(FLOOR X))))
VECTOR-REF takes a vector v and an nonnegative integer n such
that n < (VECTOR-LENGTH v) and returns ... .
----------------------------------------------------------------
WHAT DOES "OPTIONAL" MEAN?
The intent of the workshop was that extensions must not conflict
with optional features, and I should have said so. In fact some
features were made optional in order to prevent dialects from
using certain syntaxes for other purposes. It follows that #b,
#o, #d, #x, #\, and so on can't be used for any purpose other
than to support the optional feature.
I agree that the "optional" stuff about NIL and T is ridiculous.
What I should have said instead is that implementations that want
to treat NIL and T as constants can do so. In effect this is a
warning against using NIL and T to name variables. Note that
(FOO . NIL) cannot read the same as (FOO) no matter what.
I didn't mean to say that "optional" names or features are to be
preferred to essential names or features, and I don't think I did.
----------------------------------------------------------------
POOR WRITING IN THE PRELIMINARY REPORT
I agree with Kent Pitman's points regarding the use of "...",
"mistake", "respectively", and "double quote".
I agree that the set of single character tokens needs to be
better defined. I would like to include appendixes in the final
report with more rigorous descriptions of the lexical syntax, the
context-free syntax, and the denotational semantics of Scheme.
How about "The order of evaluation within a procedure call is not
specified"? That isn't quite true, of course -- normal order
evaluation is prohibited.
I should have said that some single object represents both false
and the empty list. There may be other objects representing
false. Might there be other objects representing the empty list?
(I hope not.)
I agree that it would be better to have said that (NUMBER? x)
doesn't imply (INTEGER? x).
I hope everyone noticed that it is an error to take the CAR or
CDR of the empty list.
The definition of a proper list in the preliminary manual was a
joke. The notion of a proper list has to do with finiteness,
which is not first order definable.
----------------------------------------------------------------
LEXICAL MATTERS
It is not specified whether single quote, backquote, sharp sign,
and vertical bar are delimiters that terminate symbols. The
status of these characters would be decided by a general rule
that emerged during discussion at the workshop, but not everyone
agreed to the general rule. The general rule is: Special
characters that come in pairs (left and right parenthesis, left
and right bracket, left and right curly brace, doublequote)
should be delimiters while other special characters (period and
so on) should be preceded by a space if they are to be used in
their special sense. Semicolon isn't really an exception to the
pattern because the end of line would be a delimiter anyway.
Whether vertical bar should be a delimiter according to the rule
depends on whether vertical bar is a special character that comes
in pairs, which is not specified. According to the rule single
quote, backquote, and sharp sign should not be delimiters.
> * I agree with reserving {, [, ], and }, but I would specify that they
> may be used as alphabetic according to syntactic escape conventions.
I don't understand "...according to syntactic escape conventions".
I have yet to hear of a good use for slashification of symbols.
If there is no compelling need for a feature, we should leave it
out. The workshop allowed slashification but did not encourage
it.
> * I notice that the space of symbol names is highly constrained for
> the "required subset". A property, however, that should be required
> is that within any given dialect, every interned symbol (no matter what
> characters it contains) must have a printed representation which is
> read-invertable within that dialect. I suspect that all dialects
> do this already anyway, but it should be a guaranteed property of the
> language since programmers will tend to depend on such things and should
> have a guaranteed semantics backing them up.
We probably ought to require something along these lines, but the
property you desire is too strong. It is enough that every
symbol read by the reader be printed in a form that will read
back in as the same symbol. Other symbols are too random to
worry about. In fact, I would be satisfied if only the required
set of symbol names have the property you desire. For what it's
worth, Franz Lisp does not have the property, but I doubt that
its lack is a significant cause of dissatisfaction with Franz
Lisp.
----------------------------------------------------------------
SPECIAL FORMS
LETREC vs LABELS, REC vs LABEL, and SET vs SET! are matters of
taste that needed to be decided one way or the other, and were.
History plays a significant role in decisions such as these. The
first two matters had history on both sides, but the history of
SET in traditional Lisp counts against it.
In some cases the IF, COND, and CASE special forms return
unspecified values. The SET!, DEFINE, and DEFINE! special forms,
and the SET-CAR!, SET-CDR!, and VECTOR-SET! procedures, always
return unspecified values. Except for the result of the DEFINE
form, I wrote that it is a "mistake" to use these undefined
values, and except for the results of the DEFINE and DEFINE!
forms I wrote that implementations could signal an error if the
values that were returned were "used". What I wrote is faithful
to the workshop's decisions, but I can be accused of deviating in
the cases of DEFINE and DEFINE! .
Kent is right to question what we meant by "using" a value. The
answer is that we don't know. Obviously an implementation could
return a strange value that would cause an error to be signalled
if an attempt were ever made to take its CAR or its successor; an
implementation could also arrange for an error to be signalled if
the value were ever an operand to EQ? or CONS; and there are no
doubt other things that an implementation could do as well. I
will not offer a formal description of the circumstances under
which an error could be signalled, because I want to leave room
for implementations to experiment with different approaches.
A DEFINE form is at "top level" iff it it not nested within any
other form. This definition clearly establishes circumstances
that do not count as top level, but it does not establish any
circumstances that do count as top level. I think each
implementation will have to specify circumstances under which a
DEFINE form has the described semantics, and those circumstances
would then count as top level for that implementation.
The Abelson and Sussman book uses DEFINE inside LAMBDA as
syntactic sugar. Scheme's future is tied to the success of that
book, so the sugar was dignified with "optional" status. The
optional status of the sugar required that ordinary DEFINE be
restricted to "top level".
The (DEFINE (fn . args) . body) sugar was dignified with
"optional" status for the same reason. Kent has acquired a taste
for this sugar, but I consider it a violation of orthogonality
that is doubly pernicious: (1) it discourages programmers from
thinking of procedures as objects distinct from their names; (2)
it discourages programmers from using procedures with local
state.
I agree that the optional status of named LET should imply an
optional status for named LET*, or else both named LET and named
LET* should be left out altogether. By the way, David Bartley
asks whether the body of a named let is within the scope of the
name. The Revised Report has the body within the scope of the
name. Does anyone want to argue that the body should be outside
the scope of the name?
When it was asked if DO should bind RETURN, someone said "Of
course not!", and that was the end of the discussion. If DO were
to bind RETURN I believe that DO would be the only construct in
even the optional language to bind an identifier that does not
appear explicitly in the code, and I see no reason to condone
that kind of anomaly.
----------------------------------------------------------------
DATATYPES
I was disappointed that we were unable to agree that any
datatypes were disjoint. The fact that the workshop participants
insisted on a special note to the effect that characters need not
be a distinguishable data type leads me to believe that despite
their votes most participants assumed that other data types were
distinguishable. In the final report I intend to recommend that
at the very least numbers, symbols, and pairs should be disjoint;
does anyone object?
Even without disjointness of data types, the NUMBER? and INTEGER?
predicates are useful because they define the domains of other
procedures. Thus if all strings are numbers then it must be
possible to subtract strings.
The nonsense to the effect that pairs might be indistinguishable
from vectors of length 2 is to remind folks not to assume that
pairs and vectors are disjoint. I agree that the note is out of
place and ugly.
I expect streams will be a Scheme data type, but as Kent points
out they might overlap with (say) numbers. Nonetheless the
STREAM? predicate will be useful because anything of which the
STREAM? predicate is true will have to support the operations on
streams.
----------------------------------------------------------------
PROCEDURES
I think it went without saying that escape procedures can be
called more than once. We didn't feel any need to say that the
addition procedure could be called more than once, either.
The generalizations of +, -, *, and / to arbitrary arity must
follow Common Lisp, so the ambiguity is not great. There is some
ambiguity, however, because Common Lisp has all sorts of rules
about integers, rationals, floats, and complexes that don't apply
to Scheme.
MIN and MAX are restricted from arity 0 because some
implementations don't have a smallest or largest representable
number.
Implementations should not be allowed to signal an error on
something like (=? 1 1.0). I don't think we should specify that
the result is true because you might want to implement a Scheme
in which "approximations" are a subtype of the numbers, in which
1.0 is read in as an approximation, and in which all equality
comparisons involving approximate numbers return false.
(If you haven't caught on by now, I'm perfectly comfortable with
the fact that Scheme is far less tightly specified than Common
Lisp. I believe Scheme can continue to represent the future of
Lisp only by being open to experimentation.)
I would rather not talk about "interning" a symbol, because
there is no need to talk about it when all symbols are interned.
I have to use words like "interned" to talk about implementations
in which not all symbols are interned, but for definitions I
would like to refer people to manuals for traditional Lisps.
LENGTH is defined on proper lists, and its action on anything
else is not specified.
I can't imagine a definition of APPEND! that would want to mutate
its last argument either. Shall we say it doesn't?
Kent's suggestions for MEMQ?, MEMV?, MEMBER?, ASSQ?, ASSV?, and
ASSOC? are interesting. Several people at the workshop, notably
Hal Abelson, expressed the belief that we ought to reconsider the
entire MEMBER/ASSOC complex of procedures.
MAPCAR and MAPC have their historical names for historical
reasons, and I would not be averse to renaming them eventually.
If MAPCAR is defined as follows in an implementation that
evaluates right to left, then the list of results is constructed
from right to left:
(DEFINE MAPCAR
(LAMBDA (F L)
(IF (NULL? L)
'()
(CONS (F (CAR L)) (MAPCAR F (CDR L))))))
I agree with Kent that the result of VECTOR->LIST cannot
reasonably be guaranteed to be a new object.
VECTOR-SET!, SET-CAR!, and SET-CDR! seem inconsistent to me too.
I think we should offer a prize for the best rationalization of
these names.
I think garbage collection should be treated as an issue of
performance rather than as an issue of semantics.
Peace, William Clinger
∂09-Dec-84 1307 RPG apology to Franz Lisp
∂09-Dec-84 1145 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa apology to Franz Lisp
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 9 Dec 84 11:44:54 PST
Received: from indiana by csnet-relay.csnet id ab22287; 9 Dec 84 14:36 EST
Received: by iuvax.UUCP (4.12/4.7)
id AA01074; Sun, 9 Dec 84 11:11:13 est
Date: Sun, 9 Dec 84 11:11:13 est
From: Will Clinger <willc%indiana.csnet@csnet-relay.arpa>
To: scheme@mit-mc.ARPA
Subject: apology to Franz Lisp
I apologize to Franz Lisp for claiming that not every interned symbol in
Franz has a printed representation that reads back in as the same symbol.
An example confused me but not Franz Lisp.
Peace, William Clinger
∂10-Dec-84 1123 RPG Scheme conference report
∂09-Dec-84 1648 @MIT-MC:ANDY@SU-SCORE.ARPA Scheme conference report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 9 Dec 84 16:48:24 PST
Date: Sun 9 Dec 84 16:45:14-PST
From: Andy Freeman <ANDY@SU-SCORE.ARPA>
Subject: Scheme conference report
To: scheme@MIT-MC.ARPA
Will the final report on the scheme conference say anything about
macros? There are substantial issues to be resolved/understood,
especially in scoping and expansion, but can a "least common
denominator" solution be released in the interim? How about a syntax
for defining top-level macros? That can be useful even if everything
else is undefined or optional.
Speaking of top-level solutions, why was ",." left out of the
backquote syntax? (It's like ",@", except that the value of the
following form may be destructively spliced into the result. ",@", as
you recall, non-destructively splices the value of the following form
into the result.) If deeper levels of nesting are going to be
optional, the report has to define what happens.
By the way, unless Scheme is going to define a character set, EOF
isn't necessarily a character. Neither is end-of-line.
Are all symbols interned or not? (Interning isn't necessary to print
code and be able to read it back in later.)
Still, most of these are minor issues. What the final report really
needs is a discussion of the decisions. Some things do not need
explanation (except to historians), like the names lambda and ', but,
for instance, why are true and false self-evaluating? In many cases
the decision itself is unimportant, but the issues are.
The report would also be improved by explicit mention of controversial
issues. So there's no decision; the reasons are still important.
-andy
ps - Why is argument evaluation order unspecified? That was a mistake
in Pascal, but then AND/OR/etc. have a defined order in Scheme. Then
again, so many standard forms have a right-left defined order that
consistency would suggest that user procedures should also.
Is the closure position an argument?
-------
∂10-Dec-84 1137 RPG Scheme conference report
∂09-Dec-84 1648 @MIT-MC:ANDY@SU-SCORE.ARPA Scheme conference report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 9 Dec 84 16:48:24 PST
Date: Sun 9 Dec 84 16:45:14-PST
From: Andy Freeman <ANDY@SU-SCORE.ARPA>
Subject: Scheme conference report
To: scheme@MIT-MC.ARPA
Will the final report on the scheme conference say anything about
macros? There are substantial issues to be resolved/understood,
especially in scoping and expansion, but can a "least common
denominator" solution be released in the interim? How about a syntax
for defining top-level macros? That can be useful even if everything
else is undefined or optional.
Speaking of top-level solutions, why was ",." left out of the
backquote syntax? (It's like ",@", except that the value of the
following form may be destructively spliced into the result. ",@", as
you recall, non-destructively splices the value of the following form
into the result.) If deeper levels of nesting are going to be
optional, the report has to define what happens.
By the way, unless Scheme is going to define a character set, EOF
isn't necessarily a character. Neither is end-of-line.
Are all symbols interned or not? (Interning isn't necessary to print
code and be able to read it back in later.)
Still, most of these are minor issues. What the final report really
needs is a discussion of the decisions. Some things do not need
explanation (except to historians), like the names lambda and ', but,
for instance, why are true and false self-evaluating? In many cases
the decision itself is unimportant, but the issues are.
The report would also be improved by explicit mention of controversial
issues. So there's no decision; the reasons are still important.
-andy
ps - Why is argument evaluation order unspecified? That was a mistake
in Pascal, but then AND/OR/etc. have a defined order in Scheme. Then
again, so many standard forms have a right-left defined order that
consistency would suggest that user procedures should also.
Is the closure position an argument?
-------
∂10-Dec-84 1142 RPG Scheme conference report
∂10-Dec-84 0930 @MIT-MC:JINX@MIT-OZ Scheme conference report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 10 Dec 84 09:30:02 PST
Date: 10 Dec 1984 12:24 EST (Mon)
Message-ID: <JINX.12070348515.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Andy Freeman <ANDY@SU-SCORE.ARPA>
Cc: scheme@MIT-MC.ARPA
Subject: Scheme conference report
I would like to clarify (hopefully) a few points with respect
to the evaluation of combinations:
The operator position is a "distinguished" argument. In my
opinion it is the only position for which the evaluation order might
be relevant. If reflective procedures are present in an
implementation, then the operator position must be evaluated before
any operand expressions. Since in the common subset there is no
provision for reflective procedures, there is no need to specify any
particular order with respect to the operator.
In Will's last message there was a statement to the effect
that normal order evaluation was prohibited. I find this rather
surprising. One of Guy Steele's Rabbit compiler main points was that
normal order beta-subtitution could be used very successfully to
optimize Scheme code. In the absence of side-effects, and if the
programs terminate when using applicative order, there is no way to
determine whether normal or applicative order is used. A compiler can
use this profitably to postpone evaluation. A think that a more
appropriate statement is that portable programs should not depend on
the evaluation strategy used, ie. they should work in applicative
order, but different implementations may want to use different
strategies.
The order of argument evaluation was left unspecified for
various reasons:
- The order of argument evaluation is only relevant in the
presence of side-effects in some of the argument expressions. Scheme
is predominantly an applicative language (contrast with Pascal), and
good style requires that arguments to procedures (operands of
combinations) be side-effect free. By not specifying the order, it
was felt that code with such side-effects would be discouraged since
its effect would not be predictable.
- An optimizing compiler can do a better job if it has freedom
over the order in which it can execute expressions. Leaving the order
unspecified potentially allows a clever compiler to choose the optimal
order for each combination. Note that the meaning of a program can
only be changed by reordering if the argument expressions contain
side-effects. But this code could not be guaranteed to work in other
implementations with different default order for argument evaluation.
- Leaving the order of argument evaluation unspecified allows
a parallel implementation to evaluate in parallel. Note again that
the only programs whose semantics are not clear (and are therefore not
predictable) are those with side-effects in the operands of a
combination.
A marginally related issue is the issue of macros. In Scheme
there is not so much of a need to provide a macro facility as in other
dialects of Lisp. Macros are needed only to provide "nicer", more
readable syntax. In other dialects they are needed to extend the
langauge since there is no way of encapsulating an expression and an
environment. Freezing ("thunkifying", wrapping in a lambda
expression) an argument encapsulates a context and an expression in a
procedure which can then be invoked at will by the operator procedure.
While syntactically clumsy, it is conceptually very elegant. Note
that an optimizing compiler (Rabbit, for example) can eliminate most
or all of the overhead of freezing and thawing.
∂12-Dec-84 1711 RPG Re: Scheme conference report
∂12-Dec-84 1601 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Re: Scheme conference report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 12 Dec 84 16:01:03 PST
Received: from unc by csnet-relay.csnet id aa04450; 12 Dec 84 15:04 EST
Received: by unc (4.12/4.7) id AA29958; Tue, 11 Dec 84 00:04:48 est
Date: Tue, 11 Dec 84 00:04:48 est
From: Kent Dybvig <dyb%unc.csnet@csnet-relay.arpa>
Message-Id: <8412110504.AA29958@unc>
To: ANDY@su-score.ARPA, scheme@mit-mc.ARPA
Subject: Re: Scheme conference report
Relative order of evaluation of the expressions in a combination is
not specified for at least two reasons:
1) It is poor coding style to depend on order of evaluation. If
there is an ordering constraint it should be made explicit
by using "let" or some such.
2) It is a severe constraint on the implementation for the language
to specify an evaluation order. What is easy for one machine
model or architecture may be difficult for another.
Note that Pascal and Scheme are not alone; neither C nor Common Lisp
specify the order of evaluation.
Kent Dybvig
∂12-Dec-84 1847 RPG
∂12-Dec-84 1837 KMP@MIT-MC
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 12 Dec 84 18:37:11 PST
Date: 12 December 1984 21:37-EST
From: Kent M Pitman <KMP @ MIT-MC>
To: dyb%unc.csnet @ CSNET-RELAY
cc: SCHEME @ MIT-MC
Actually, Common Lisp does specify the order of evaluation as left to right.
It's tricky to find the passages in the CL manual which assure this, but
they are there if you look hard enough. The issue came up recently in the
Common Lisp discussion group and subsided after various obscure but recently
conclusive passages were cited.
Anyway, I agree it is reasonable to leave the order unspecified. It may be
computationally infeasible for the compiler to determine when order of
evaluation matters in many situations where "better code" would be available
if such a determination could be made.
∂15-Dec-84 2257 RPG Scheme bibliography
∂15-Dec-84 1655 @MIT-MC:CPH@MIT-OZ Scheme bibliography
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 15 Dec 84 16:55:16 PST
Date: Sat, 15 Dec 1984 19:53 EST
Message-ID: <CPH.12071740976.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: linus!ramsdell%UUCP@YALE.ARPA (John D. Ramsdell)
Cc: T-Discussion%MIT-OZ@MIT-MC.ARPA, Scheme@MIT-MC
Subject: Scheme bibliography
In-reply-to: Msg of 14 Dec 1984 13:44-EST
Fri 14 Dec 84 09:26:47 est from linus!ramsdell at Mitre-Bedford,
linus!ramsdell%UUCP at YALE.ARPA (John D. Ramsdell)
I believe that this is a complete list of the early Scheme papers:
Steele, Guy Lewis, Jr., and Gerald Jay Sussman. 1975. Scheme: An
interpreter for the extended lambda calculus. Memo 349, MIT
Artificial Intelligence Laboratory.
Steele, Guy Lewis, Jr., and Gerald Jay Sussman. 1976. Lambda: The
ultimate imperative. Memo 353, MIT Artificial Intelligence
Laboratory.
Steele, Guy Lewis, Jr. 1976. Lambda: The ultimate declarative. Memo
379, MIT Artificial Intelligence Laboratory.
Steele, Guy Lewis, Jr. 1977. Debunking the "expensive procedure
call" myth. In Proceedings of the National Conference of the ACM, pp.
153-62.
Steele, Guy Lewis, Jr., and Gerald Jay Sussman. January 1978. The
revised report on Scheme: A dialect of Lisp. Memo 452, MIT Artificial
Intelligence Laboratory.
Sussman, Gerald Jay, and Guy Lewis Steele, Jr. May 1978. The art of
the interpreter or, The modularity complex. Memo 452, MIT Artificial
Intelligence Laboratory.
Steele, Guy Lewis, Jr. May 1978. Rabbit: A compiler for Scheme.
Technical report 474, MIT Artificial Intelligence Laboratory.
∂16-Dec-84 2313 RPG continuation terminology
∂16-Dec-84 2039 @MIT-MC:cth%indiana.csnet@csnet-relay.arpa continuation terminology
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 16 Dec 84 20:39:11 PST
Received: from indiana by csnet-relay.csnet id a001364; 16 Dec 84 23:35 EST
Received: by iuvax.UUCP (4.12/4.7)
id AA04292; Sun, 16 Dec 84 17:27:40 est
Date: Sun, 16 Dec 84 17:27:40 est
From: Chris Haynes <cth%indiana.csnet@csnet-relay.arpa>
To: scheme@mit-mc.ARPA
Subject: continuation terminology
We object strongly to the use of the term "escape procedure". The word
"escape" is far to limiting to describe continuations, which are good for so
much more. Also, the term "escape procedure" is strongly associated with the
limited facility by that name provided by most Lisp systems (which isn't good
for much besides "escaping"). If we adopt the old Lisp name, many will
assume that continuations aren't good for anything more than Lisp escape
procedures, and will miss what we feel is one of the most important
distinguishing features of Scheme.
We find the term "continuation" to be quit satisfactory in most contexts, and
it agrees with the name "call-with-current-continuation". However, we
recognize that in the context of denotational semantics or implementation
discussions, there is possibility of confusing continuations as first-class
programming objects and their semantic or implementation counterparts. Thus
additional terminology is desirable when such distinctions must be made, and
to standardize such terminology it should probably be used in the Revised
Revised Report. We suggest the term "continuation object" for this purpose,
though it is not wonderful and we welcome other suggestions.
-- Chris Haynes
Dan Friedman
Eugene Kohlbecker
∂17-Dec-84 1524 RPG continuation terminology
∂17-Dec-84 1523 JAR@MIT-MC continuation terminology
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 17 Dec 84 15:23:41 PST
Date: 17 December 1984 18:23-EST
From: Jonathan A Rees <JAR @ MIT-MC>
Subject: continuation terminology
To: cth%indiana.csnet @ CSNET-RELAY
cc: SCHEME @ MIT-MC
In-reply-to: Msg of Sun 16 Dec 84 17:27:40 est from Chris Haynes <cth%indiana.csnet at csnet-relay.arpa>
Date: Sun, 16 Dec 84 17:27:40 est
From: Chris Haynes <cth%indiana.csnet at csnet-relay.arpa>
We object strongly to the use of the term "escape procedure"...
My only objection to the terms "continuation" and "continuation object"
is that the presence of fluids and/or UNWIND-PROTECT mean that the thing
created by the user-visible CATCH or CONTINUE or CALL-... or whatever is
more than just a continuation, since it implicitly includes a reference
to the dynamic state. There is a low-level thing which really does give
you a continuation, but I expect that the mechanism which does the right
thing with fluids would be the normal one used by users.
I don't have any new alternative term to propose, however.
Of course, we decided not to decide whether or not the essential
scheme's continuation procuration combinator dealt properly with fluids,
since essential scheme doesn't deal with fluids at all. It seems to me
that any fluid mechanism whatsoever must distinguish between
continuations and continuation+state things. As things are, my guess is
that it would be up to the implementor which of these two things the
essential dialect's CALL-... gives you. (This might be the wrong thing,
but I won't argue that position here - this message is already too long.)
(By the way, no Lisp has never had escape procedures per se; the usual
CATCH/THROW mechanism doesn't introduce a new kind of object. I'm not
convinced that the term "escape procedure" is as broken as you think it
is, or that it necessarily has such strong connotations. But I'm not
partial to the term.)
∂18-Dec-84 2009 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Common Lisp order of evaluation
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 18 Dec 84 20:09:07 PST
Received: from unc by csnet-relay.csnet id ac00691; 18 Dec 84 14:57 EST
Received: by unc (4.12/4.7) id AA12698; Fri, 14 Dec 84 10:29:23 est
Date: Fri, 14 Dec 84 10:29:23 est
From: Kent Dybvig <dyb%unc.csnet@csnet-relay.arpa>
Message-Id: <8412141529.AA12698@unc>
To: KMP@mit-mc.ARPA, SCHEME@mit-mc.ARPA
Subject: Common Lisp order of evaluation
If you have found passages which indicate a specific order of
evaluation, I'd like to know about it. All that I have found
in scouring the manual several times over, in several different
versions over the years, is that arguments are 'processed' in
left-right order *once they reach the caller*. Regardless of
any intentions on the designer's part, or any decisions of
discussion groups, any feature of the language that is not
spelled out is subject to interpretation. There is certainly
nowhere in the manual that states that arguments are evaluated
in left-right order.
∂19-Dec-84 0850 @MIT-MC:rhh@MIT-VAX Re: Common Lisp order of evaluation
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 19 Dec 84 08:49:55 PST
Received: by mit-vax.Mit-chaos.Arpa (4.12/4.8) id AA25785; Wed, 19 Dec 84 11:40:26 est
Date: Wed, 19 Dec 84 11:40:26 est
From: Bert Halstead <rhh@mit-vax>
To: KMP@mit-mc.ARPA, SCHEME@mit-mc.ARPA, dyb%unc.csnet@csnet-relay.arpa
Subject: Re: Common Lisp order of evaluation
The following passages out of the Common Lisp book may be relevant:
"setf carefully arranges to preserve the usual left-to-right order
in which the various subforms are evaluated." (p. 97)
"Macros that manipulate generalized variables must guarantee the
'obvious' semantics: subforms of generalized-variable references
are evaluated exactly as many times as they appear in the source
program, and they are evaluated in the same order as they appear
in the source program." (p. 99)
-Bert
∂19-Dec-84 0912 @MIT-MC:CPH@MIT-OZ Common Lisp order of evaluation
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 19 Dec 84 09:12:05 PST
Date: Wed, 19 Dec 1984 12:12 EST
Message-ID: <CPH.12072705547.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: Scheme@MIT-MC
Subject: Common Lisp order of evaluation
In-reply-to: Msg of 19 Dec 1984 11:40-EST from Bert Halstead <rhh at mit-vax>
Come on, folks... This really isn't a great place to argue about what
order Common Lisp evaluates its arguments. I for one don't care and
would rather not know.
∂23-Dec-84 0901 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa length vs. list-length
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 23 Dec 84 09:00:57 PST
Received: from unc by csnet-relay.csnet id ag24249; 23 Dec 84 11:49 EST
Received: by unc (4.12/4.7) id AA29885; Sun, 23 Dec 84 01:06:25 est
Date: Sun, 23 Dec 84 01:06:25 est
From: Kent Dybvig <dyb%unc.csnet@csnet-relay.arpa>
Message-Id: <8412230606.AA29885@unc>
To: scheme@mit-mc.ARPA
Subject: length vs. list-length
My primary concern about the length function seems to have been
lost in the ensuing discussions. I do not insist that Scheme
have a generic length function. I do insist that the naming
convention for such functions be consistent.
Doesn't this look a little odd?
(define generic-length
(lambda (x)
(cond ((string? x) (string-length x))
((vector? x) (vector-length x))
((list? x) (length x)))))
I like this much better:
(define generic-length
(lambda (x)
(cond ((string? x) (string-length x))
((vector? x) (vector-length x))
((list? x) (list-length x)))))
We have list-ref, vector-ref and string-ref. Why should we not
have list-length rather than length? While we're at it, why
not have list-append rather than append? Any functions that makes
sense for strings, lists, and vectors should be named with
the appropriate type-name prefix. (Even though the language
doesn't specify a reverse function for vectors or strings
and since such functions would be reasonable, the reverse
function for lists should be named list-reverse.)
∂23-Dec-84 2330 @MIT-MC:mw%brandeis.csnet@csnet-relay.arpa list-length
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 23 Dec 84 23:30:17 PST
Received: from brandeis by csnet-relay.csnet id a026028; 24 Dec 84 2:15 EST
Received: by brandeis.ARPA (4.12/)
id AA06312; Sun, 23 Dec 84 22:31:44 est
Date: 23 Dec 1984 22:30-EST
From: mw%brandeis.csnet@csnet-relay.arpa
In-Real-Life: Mitchell Wand,faculty
Subject: list-length
To: scheme@mit-mc.ARPA
Cc: dyb%unc.csnet@csnet-relay.arpa
Message-Id: <472707016/mw@brandeis>
I vote for list-length over length, too. I think we just went over
that one a little too rapidly at the meeting.
-- Mitch Wand
∂24-Dec-84 1350 @MIT-MC:mw%brandeis.csnet@csnet-relay.arpa list-length
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 24 Dec 84 13:50:48 PST
Received: from brandeis by csnet-relay.csnet id a026028; 24 Dec 84 2:15 EST
Received: by brandeis.ARPA (4.12/)
id AA06312; Sun, 23 Dec 84 22:31:44 est
Date: 23 Dec 1984 22:30-EST
From: mw%brandeis.csnet@csnet-relay.arpa
In-Real-Life: Mitchell Wand,faculty
Subject: list-length
To: scheme@mit-mc.ARPA
Cc: dyb%unc.csnet@csnet-relay.arpa
Message-Id: <472707016/mw@brandeis>
I vote for list-length over length, too. I think we just went over
that one a little too rapidly at the meeting.
-- Mitch Wand
∂28-Dec-84 1428 JAR@MIT-MC list-length
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Dec 84 14:28:26 PST
Date: 28 December 1984 17:29-EST
From: Jonathan A Rees <JAR @ MIT-MC>
Subject: list-length
To: SCHEME @ MIT-MC
In-reply-to: Msg of 23 Dec 1984 22:30-EST from mw%brandeis.csnet at csnet-relay.arpa
LIST-APPEND, LIST-REVERSE, LIST-SORT, LIST-MAPCAR, ...
∂13-Jan-85 1322 JAR@MIT-MC list-length
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 13 Jan 85 13:21:53 PST
Date: 13 January 1985 16:22-EST
From: Jonathan A Rees <JAR @ MIT-MC>
Subject: list-length
To: willc%indiana.csnet @ CSNET-RELAY
cc: SCHEME @ MIT-MC
In-reply-to: Msg of Fri 4 Jan 85 15:50:17 est from Will Clinger <willc%indiana.csnet at csnet-relay.arpa>
Date: Fri, 4 Jan 85 15:50:17 est
From: Will Clinger <willc%indiana.csnet at csnet-relay.arpa>
Pardon me, but I am not certain whether your recent message (LIST-APPEND,
LIST-REVERSE, LIST-SORT, LIST-MAPCAR, ...) was in support of or in derision
of the proposal that the operations on lists be prefixed by LIST- .
Neither, really. The intent of the message was to ask "where do you
draw the line?". E.g. APPEND / STRING-APPEND have the same problem that
LENGTH / STRING-LENGTH do. If you're not careful you end up putting
data type prefixes on everything (as you might have to in a strongly typed
language without unions, like PASCAL) or nothing (as in a fully generic
language like Smalltalk). What policy should we adopt?
∂13-Jan-85 1328 KMP@MIT-MC policy to adopt
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 13 Jan 85 13:28:24 PST
Date: 13 January 1985 16:28-EST
From: Kent M Pitman <KMP @ MIT-MC>
Subject: policy to adopt
To: SCHEME @ MIT-MC
i think we should clearly re-emphasize what our rationale is for wanting
any standard before deciding a policy. if the only purpose is to be able
to write papers that use common syntax, the policy might want to be different
than if we plan to port code. as much as we are not trying to make a
Common Scheme, some of the trends in this discussion have leaned pretty
strongly in that direction, perhaps overly so in some cases. i can elaborate
if it becomes appropriate to do so; i'll let it go at that for now.
-kmp
∂13-Jan-85 2117 @MIT-MC:CPH@MIT-OZ Scheme String Operations: the Report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 13 Jan 85 21:17:18 PST
Date: Mon, 14 Jan 1985 00:17 EST
Message-ID: <CPH.12079391220.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>,
Jensen%ti-csl.csnet@CSNET-RELAY.ARPA,
Oxley%ti-csl.csnet@CSNET-RELAY.ARPA, Scheme@MIT-MC
Subject: Scheme String Operations: the Report
In-reply-to: Msg of 13 Jan 1985 15:14-EST from CPH
Here is the preliminary report... Comments and suggestions?
----------------------------------------------------------------------
Scheme String Operations
Notes:
[] Strings are mutable vectors of characters.
[] The string datatype described here has very little dependence on
the character datatype from which it is built. Thus it may correspond
to either of Common Lisp's STRING or SIMPLE-STRING datatypes. In MIT
Scheme, the character datatype is a special extended ASCII.
[] Historically, two different methods have been used to specify
substrings: [1] a starting index and a length, and [2] a starting
index and an ending index. Often both methods have been used for
different operations in the same data abstraction.
The arguments in favor of one method or the other seem fairly
uninteresting, but it does seem important to pick one method and use
it exclusively. The latter method has been chosen, for no
particularly good reason.
Naming conventions:
[] Character-wise operations are normally specified in two forms, one
which operates on a substring, and another which operates on an entire
string. The former is usually named "SUBSTRING-..." and the latter
"STRING-...".
[] Operations for which case sensitivity has meaning are specified in
two forms, a case-sensitive version and a case-insensitive version.
The latter is given the suffix "-CI" to distinguish it; if the
operation is a predicate, the suffix precedes the "?" at the end of
the name.
[] Currently, operation pairs which are "directed" will be given
similar names, such as, "STRING-FIND-NEXT-CHAR" and
"STRING-FIND-PREVIOUS-CHAR". However, there are 3 different syllable
pairs used to distinguish these operations: "LEFT"/"RIGHT",
"PREVIOUS"/"NEXT", and "FORWARD"/"BACKWARD". In each case the
particular pair was chosen for its meaning, but it may be better to
name them more consistently.
!
----------------------------------------------------------------------
Definitions
[] The phrases "X is a string" and "the string X" mean that X is an
object which satisfies the STRING? predicate. Similarly, "X is a
character" means that X satisfies the CHAR? predicate.
[] The "length" of a string is the number of characters that it
contains. This number is a non-negative integer that is determined at
the time of the string's creation.
[] The phrase "X is a valid index of Y", where Y is a string, means
that X is a non-negative integer that is strictly less than the length
of Y. The index 0 refers to the first character, 1 to the second,
etc.
[] The phrase "<X,Y,Z> is a substring" means that:
1. X is a string.
2. Both Y and Z are non-negative integers.
3. Z is less than or equal to the length of X.
4. Y is less than or equal to Z.
This refers to that substring of X starting at Y (inclusive) and
ending at Z (exclusive). If Y is equal to Z, the substring is empty.
[] The directions "left" and "right" refer to numerically decreasing
and numerically increasing indices, respectively. Alternate names for
these directions are (respectively): "previous" and "next"; "backward"
and "forward".
!
----------------------------------------------------------------------
Basic Character Operations
These are the operations on characters that are required by the string
data abstraction. The names of these operations are irrelevant; only
the functionality is required.
(CHAR-EQUAL? CHAR1 CHAR2)
(CHAR-EQUAL-CI? CHAR1 CHAR2)
These predicates are true iff CHAR1 and CHAR2 are the same character.
The former operation is case sensitive, while the latter is not. Both
CHAR1 and CHAR2 must be characters.
(CHAR-LESS? CHAR1 CHAR2)
(CHAR-LESS-CI? CHAR1 CHAR2)
These predicates are true iff CHAR1 is strictly less than CHAR2 in the
character ordering. The former operation is case sensitive, while the
latter is not. Both CHAR1 and CHAR2 must be characters.
(CHAR-UPPER-CASE? CHAR)
(CHAR-LOWER-CASE? CHAR)
These predicates should be true only of upper and lower case
alphabetic characters, respectively. CHAR must be a character.
(CHAR-UPCASE CHAR)
(CHAR-DOWNCASE CHAR)
These operations convert alphabetic characters to upper and lower
case, respectively. If CHAR is not alphabetic, it is returned. CHAR
must be a character.
Character-sets
A character-set is an abstract object that represents a (mathematical)
set of characters. Character-set searches are most useful for parsing
strings. The required operations on character-sets are:
(CHAR-SET-MEMBER? CHAR-SET CHAR)
A predicate which is true iff the character CHAR is a member of the
character-set CHAR-SET.
!
----------------------------------------------------------------------
Basic String Operations
These are the most primitive of the string operations. All other
string operations can be constructed from these.
(STRING-ALLOCATE LENGTH)
This operation allocates a new string, of the given LENGTH, and
returns it. The contents of the string are unspecified. LENGTH must
be a non-negative integer.
(STRING? OBJECT)
This is a boolean operation which is true of all strings.
(STRING-LENGTH STRING)
This operation returns the length of STRING, which must be a string.
The value is a non-negative integer.
(STRING-REF STRING INDEX)
This operation returns the INDEX'th element of STRING, a character.
STRING must be a string, and INDEX must be a valid index of STRING.
(STRING-SET! STRING INDEX CHAR)
This operation stores the character CHAR as the INDEX'th element of
STRING. STRING must be a string, INDEX must be a valid index of
STRING, and CHAR must be a character.
!
----------------------------------------------------------------------
Standard Operations
These operations are useful enough to deserve being "standard" in most
implementations.
(MAKE-STRING LENGTH CHAR)
This allocates a new string of the given LENGTH, and initializes all
of its elements to CHAR. LENGTH must be a non-negative integer, and
CHAR must be a character.
(STRING-FILL! STRING CHAR)
This fills the string STRING with the character CHAR.
(STRING-NULL? STRING)
This predicate is true only of strings whose length is zero. STRING
must be a string.
(SUBSTRING STRING START END)
This operation returns a new string, which is the substring designated
by <STRING, START, END>; this must be a valid substring designator.
(STRING-APPEND STRING1 STRING2)
This operation returns a new string, which is the concatenation of
STRING1 followed by STRING2, both of which must be strings. This
operation may (optionally) be n-ary, for n greater than 0.
(STRING-COPY STRING)
This operation returns a new copy of STRING, which must be a string.
(STRING->LIST STRING)
(LIST->STRING CHARS)
These operations convert between strings and lists of characters.
STRING must be a string, and CHARS must be a list of characters. The
result of either operation is a newly-created object of the
appropriate form.
!
----------------------------------------------------------------------
Motion Primitives
These operations are useful because they can be used to construct many
other string operations, e.g. SUBSTRING and STRING-APPEND. If strings
are implemented in the usual way on conventional machines, these
operations are extremely simple to implement. It is also possible to
in-line code them in some cases.
(SUBSTRING-FILL! STRING START END CHAR)
This fills the substring <STRING, START, END> with the character CHAR.
(SUBSTRING-MOVE-RIGHT! STRING1 START1 END1 STRING2 START2)
(SUBSTRING-MOVE-LEFT! STRING1 START1 END1 STRING2 START2)
These operations destructively copy the substring <STRING1, START1,
END1> to the string STRING2 starting at the index START2. It must be
the case that <STRING2, START2, (+ START2 (- END1 START1))> is a
substring; this latter substring is destructively modified to contain
the contents of the former substring.
The operations differ only when the two substrings overlap, i.e. when
STRING1 and STRING2 are EQ? and the index sets of the substrings are
not disjoint. In this case, the operations are defined to copy the
elements of the first substring serially. SUBSTRING-MOVE-RIGHT!
copies the first substring from left to right, while
SUBSTRING-MOVE-LEFT! copies from right to left. Thus, for example,
the two operations can be used to shift groups of characters right or
left, respectively, within a given string.
!
----------------------------------------------------------------------
Comparison Primitives
Each group of comparisons contains these operations:
1. Compare two substrings, case sensitive.
2. Compare two strings, case sensitive.
3. Compare two substrings, case insensitive.
4. Compare two strings, case insensitive.
The groups are described as a unit since they are essentially very
similar. In all cases the arguments must be valid substrings or
strings.
(SUBSTRING-EQUAL? STRING1 START1 END1 STRING2 START2 END2)
(STRING-EQUAL? STRING1 STRING2)
(SUBSTRING-EQUAL-CI? STRING1 START1 END1 STRING2 START2 END2)
(STRING-EQUAL-CI? STRING1 STRING2)
These are boolean equality predicates, which are true only when the
two (sub)strings are the same length and contain the same characters.
(SUBSTRING-LESS? STRING1 START1 END1 STRING2 START2 END2)
(STRING-LESS? STRING1 STRING2)
(SUBSTRING-LESS-CI? STRING1 START1 END1 STRING2 START2 END2)
(STRING-LESS-CI? STRING1 STRING2)
These are boolean order predicates, which compare the (sub)strings
using the standard dictionary order; i.e. the leftmost unequal
characters determine the order, or if no such character exists, the
shorter (sub)string is less. The character ordering is determined by
the character operations CHAR-LESS? and CHAR-LESS-CI?.
(SUBSTRING-MATCH-FORWARD STRING1 START1 END1 STRING2 START2 END2)
(STRING-MATCH-FORWARD STRING1 STRING2)
(SUBSTRING-MATCH-FORWARD-CI STRING1 START1 END1 STRING2 START2 END2)
(STRING-MATCH-FORWARD-CI STRING1 STRING2)
These operations compare the (sub)strings from left to right,
returning the number of characters that were the same.
(SUBSTRING-MATCH-BACKWARD STRING1 START1 END1 STRING2 START2 END2)
(STRING-MATCH-BACKWARD STRING1 STRING2)
(SUBSTRING-MATCH-BACKWARD-CI STRING1 START1 END1 STRING2 START2 END2)
(STRING-MATCH-BACKWARD-CI STRING1 STRING2)
These operations compare the (sub)strings from right to left,
returning the number of characters that were the same.
!
----------------------------------------------------------------------
Character Search Primitives
Each group of searches contains these operations:
1. Search substring for character, case sensitive.
2. Search string for character, case sensitive.
3. Search substring for character, case insensitive.
4. Search string for character, case insensitive.
5. Search substring for character in set.
6. Search string for character in set.
In all cases the arguments must be valid substrings, strings,
characters, or character-sets, as appropriate.
(SUBSTRING-FIND-NEXT-CHAR STRING START END CHAR)
(STRING-FIND-NEXT-CHAR STRING CHAR)
(SUBSTRING-FIND-NEXT-CHAR-CI STRING START END CHAR)
(STRING-FIND-NEXT-CHAR-CI STRING CHAR)
(SUBSTRING-FIND-NEXT-CHAR-IN-SET STRING START END CHAR-SET)
(STRING-FIND-NEXT-CHAR-IN-SET STRING CHAR-SET)
These operations return the index of the leftmost occurrence of the
character CHAR (or character-set CHAR-SET) within the given
(sub)string, or #!FALSE if there is no occurrence.
(SUBSTRING-FIND-PREVIOUS-CHAR STRING START END CHAR)
(STRING-FIND-PREVIOUS-CHAR STRING CHAR)
(SUBSTRING-FIND-PREVIOUS-CHAR-CI STRING START END CHAR)
(STRING-FIND-PREVIOUS-CHAR-CI STRING CHAR)
(SUBSTRING-FIND-PREVIOUS-CHAR-IN-SET STRING START END CHAR-SET)
(STRING-FIND-PREVIOUS-CHAR-IN-SET STRING CHAR-SET)
These operations return the index of the rightmost occurrence of the
character CHAR (or character-set CHAR-SET) within the given
(sub)string, or #!FALSE if there is no occurrence.
!
----------------------------------------------------------------------
Case
Each of the following groups contains the following operations:
1. A predicate to determine a substring's case.
2. A predicate to determine a string's case.
3. A operation to destructively set a substring's case.
4. A operation to destructively set a string's case.
The meanings of the operations should be clear from their names.
(SUBSTRING-UPPER-CASE? STRING START END)
(STRING-UPPER-CASE? STRING)
(SUBSTRING-UPCASE! STRING START END)
(STRING-UPCASE! STRING)
(SUBSTRING-LOWER-CASE? STRING START END)
(STRING-LOWER-CASE? STRING)
(SUBSTRING-DOWNCASE! STRING START END)
(STRING-DOWNCASE! STRING)
(SUBSTRING-CAPITALIZED? STRING START END)
(STRING-CAPITALIZED? STRING)
(SUBSTRING-CAPITALIZE! STRING START END)
(STRING-CAPITALIZE! STRING)
The (sub)string in the ...CAPITALIZE... operations may not be null.
!
----------------------------------------------------------------------
Appendix: An Implementation
The following is an examplary implementation of the above string
operations (in terms of the basic operations). This implementation is
intended to supplement the preceding specification by providing an
explicit formal description of the semantics of the operations.
There is no error checking in this code, since it was felt that it
would obscure the form somewhat.
!
;;;; Standard Operations
(define (make-string length char)
(let ((result (string-allocate length)))
(substring-fill! result 0 length char)
result))
(define (string-fill! string char)
(substring-fill! string 0 (string-length string) char))
(define (string-null? string)
(zero? (string-length string)))
(define (substring string start end)
(let ((result (string-allocate (- end start))))
(substring-move-right! string start end result 0)
result))
(define (string-append string1 string2)
(let ((length1 (string-length string1))
(length2 (string-length string2)))
(let ((result (string-allocate (+ length1 length2))))
(substring-move-right! string1 0 length1 result 0)
(substring-move-right! string2 0 length2 result length1)
result)))
(define (string-copy string)
(let ((length (string-length string)))
(let ((result (string-allocate length)))
(substring-move-right! string 0 length result 0)
result)))
(define (string->list string)
(let ((end (string-length string)))
(define (loop index)
(if (= index end)
'()
(cons (string-ref string index)
(loop (1+ index)))))
(loop 0)))
(define (list->string chars)
(let ((result (string-allocate (length chars))))
(define (loop index chars)
(if (null? chars)
result
(begin (string-set! result index (car chars))
(loop (1+ index) (cdr chars)))))
(loop 0 chars)))
!
;;;; Motion Primitives
(define (substring-fill! string start end char)
(define (loop index)
(if (not (= index end))
(begin (string-set! string index char)
(loop (1+ index)))))
(loop start))
(define (substring-move-right! string1 start1 end1 string2 start2)
(define (loop index1 index2)
(if (not (= index1 end1))
(begin (string-set! string2 index2 (string-ref string1 index1))
(loop (1+ index1) (1+ index2)))))
(loop start1 start2))
(define (substring-move-left! string1 start1 end1 string2 start2)
(define (loop index1 index2)
(if (not (= index1 start1))
(begin (string-set! string2
(-1+ index2)
(string-ref string1 (-1+ index1)))
(loop (-1+ index1) (-1+ index2)))))
(loop end1 end2))
!
;;;; Comparison Primitives
(define substring-equal?)
(define substring-equal-ci?)
(let ()
(define (make-substring-equal? char-equal?)
(lambda (string1 start1 end1 string2 start2 end2)
(define (loop index1 index2)
(or (= index1 end1)
(and (char-equal? (string-ref string1 index1)
(string-ref string2 index2))
(loop (1+ index1) (1+ index2)))))
(and (= (- end1 start1) (- end2 start2))
(loop start1 start2))))
(set! substring-equal?
(make-substring-equal? char-equal?))
(set! substring-equal-ci?
(make-substring-equal? char-equal-ci?)))
(define substring-less?)
(define substring-less-ci?)
(let ()
(define (make-substring-less? char-equal? char-less?)
(lambda (string1 start1 end1 string2 start2 end2)
(define (loop index1 index2)
(cond ((or (= index1 end1)
(= index2 end2))
(< (- end1 start1)
(- end2 start2)))
((char-equal? (string-ref string1 index1)
(string-ref string2 index2))
(loop (1+ index1) (1+ index2)))
(else
(char-less? (string-ref string1 index1)
(string-ref string2 index2)))))
(loop start1 start2)))
(set! substring-less?
(make-substring-less? char-equal? char-less?))
(set! substring-less-ci?
(make-substring-less? char-equal-ci? char-less-ci?)))
(define substring-match-forward)
(define substring-match-forward-ci)
(let ()
(define (make-substring-match-forward char-equal?)
(lambda (string1 start1 end1 string2 start2 end2)
(define (loop index1 index2 n)
(if (or (= index1 end1)
(= index2 end2)
(not (char-equal? (string-ref string1 index1)
(string-ref string2 index2))))
n
(loop (1+ index2) (1+ index2) (1+ n))))
(loop start1 start2 0)))
(set! substring-match-forward
(make-substring-match-forward char-equal?))
(set! substring-match-forward-ci
(make-substring-match-forward char-equal-ci?)))
!
(define substring-match-backward)
(define substring-match-backward-ci)
(let ()
(define (make-substring-match-backward char-equal?)
(lambda (string1 start1 end1 string2 start2 end2)
(define (loop index1 index2 n)
(if (or (= index1 start1)
(= index2 start2)
(not (char-equal? (string-ref string1 (-1+ index1))
(string-ref string2 (-1+ index2)))))
n
(loop (-1+ index2) (-1+ index2) (1+ n))))
(loop end1 end2 0)))
(set! substring-match-backward
(make-substring-match-backward char-equal?))
(set! substring-match-backward-ci
(make-substring-match-backward char-equal-ci?)))
(define string-equal?)
(define string-equal-ci?)
(define string-less?)
(define string-less-ci?)
(define string-match-forward)
(define string-match-forward-ci)
(define string-match-backward)
(define string-match-backward-ci)
(let ()
(define (string-comparison substring-comparison)
(lambda (string1 string2)
(substring-comparison string1 0 (string-length string1)
string2 0 (string-length string2))))
(set! string-equal?
(string-comparison substring-equal?))
(set! string-equal-ci?
(string-comparison substring-equal-ci?))
(set! string-less?
(string-comparison substring-less?))
(set! string-less-ci?
(string-comparison substring-less-ci?))
(set! string-match-forward
(string-comparison substring-match-forward))
(set! string-match-forward-ci
(string-comparison substring-match-forward-ci))
(set! string-match-backward
(string-comparison substring-match-backward))
(set! string-match-backward-ci
(string-comparison substring-match-backward-ci)))
!
;;;; Character Search Primitives
(define substring-find-next-char)
(define substring-find-next-char-ci)
(define substring-find-next-char-in-set)
(let ()
(define (find-next char-test)
(lambda (string start end key)
(define (loop index)
(and (not (= index end))
(if (char-test key (string-ref string index))
index
(loop (1+ index)))))
(loop start)))
(set! substring-find-next-char (find-next char-equal?))
(set! substring-find-next-char-ci (find-next char-equal-ci?))
(set! substring-find-next-char-in-set (find-next char-set-member?)))
(define substring-find-previous-char)
(define substring-find-previous-char-ci)
(define substring-find-previous-char-in-set)
(let ()
(define (find-previous char-test)
(lambda (string start end key)
(define (loop index)
(and (not (= index start))
(let ((index (-1+ index)))
(if (char-test key (string-ref string index))
index
(loop index)))))
(loop end)))
(set! substring-find-previous-char (find-previous char-equal?))
(set! substring-find-previous-char-ci (find-previous char-equal-ci?))
(set! substring-find-previous-char-in-set (find-previous char-set-member?)))
(define string-find-next-char)
(define string-find-next-char-ci)
(define string-find-next-char-in-set)
(define string-find-previous-char)
(define string-find-previous-char-ci)
(define string-find-previous-char-in-set)
(let ()
(define (string-search substring-search)
(lambda (string char)
(substring-search string 0 (string-length string) char)))
(set! string-find-next-char
(string-search substring-find-next-char))
(set! string-find-next-char-ci
(string-search substring-find-next-char-ci))
(set! string-find-next-char-in-set
(string-search substring-find-next-char-in-set))
(set! string-find-previous-char
(string-search substring-find-previous-char))
(set! string-find-previous-char-ci
(string-search substring-find-previous-char-ci))
(set! string-find-previous-char-in-set
(string-search substring-find-previous-char-in-set)))
!
;;;; Case
(define substring-upper-case?)
(define substring-lower-case?)
(let ()
(define (substring-has-case? char-has-case?)
(lambda (string start end)
(define (loop index)
(or (= index end)
(and (char-has-case? (string-ref string index))
(loop (1+ index)))))
(loop start)))
(set! substring-upper-case?
(substring-has-case? char-upper-case?))
(set! substring-lower-case?
(substring-has-case? char-lower-case?)))
(define substring-upcase!)
(define substring-downcase!)
(let ()
(define (substring-set-case! char-set-case)
(lambda (string start end)
(define (loop index)
(if (not (= index end))
(begin (string-set! string
index
(char-set-case (string-ref string index)))
(loop (1+ index)))))
(loop start)))
(set! substring-upcase!
(substring-set-case! char-upcase))
(set! substring-downcase!
(substring-set-case! char-downcase)))
(define (substring-capitalized? string start end)
(define (loop end)
(or (= end end)
(and (char-lower-case? (string-ref string end))
(loop (1+ end)))))
(and (not (= start end))
(char-upper-case? (string-8b-ref string 0))
(loop (1+ start))))
(define (substring-capitalize! string start end)
(substring-upcase! string start (1+ start))
(substring-downcase! string (1+ start) end))
(define string-upper-case?)
(define string-lower-case?)
(define string-upcase!)
(define string-downcase!)
(define string-capitalized?)
(define string-capitalize!)
(let ()
(define (string-op substring-op)
(lambda (string)
(substring-op string 0 (string-length string))))
(set! string-upper-case?
(string-op substring-upper-case?))
(set! string-lower-case?
(string-op substring-lower-case?))
(set! string-upcase!
(string-op substring-upcase!))
(set! string-downcase!
(string-op substring-downcase!))
(set! string-capitalized?
(string-op substring-capitalized?))
(set! string-capitalize!
(string-op substring-capitalize!)))
∂14-Jan-85 0217 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Re: policy to adopt
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 14 Jan 85 02:16:54 PST
Received: from unc by csnet-relay.csnet id a000234; 14 Jan 85 5:09 EST
Received: by unc (4.12/4.7) id AA00749; Sun, 13 Jan 85 22:21:36 est
Date: Sun, 13 Jan 85 22:21:36 est
From: Kent Dybvig <dyb%unc.csnet@csnet-relay.arpa>
Message-Id: <8501140321.AA00749@unc>
To: KMP@mit-mc.ARPA, SCHEME@mit-mc.ARPA
Subject: Re: policy to adopt
I have certainly gotten the impression that everyone WAS after
a Common Scheme of sorts, and not just so that papers use common
syntax. Why standardize on so many of the function names? More
importantly, why standardize on the controversial nil/t/boolean
issue? Why have numbers and streams subcommittees?
I think we need more discussion of the details of the proposal
rather than less. Standardizing is dangerous if done only half-
heartedly. We must be absolutely sure of what we standardize on,
since we will likely be stuck with our decisions for several
years.
As for the list-length, list-append issue, I think we ought to take
one of two stances:
Stance 1: sequence-type functions such as ref, length and
append should be prefixed by "list-" for the
list version, "string-" for the string version,
and "vector-" for the vector version.
Stance 2: sequence-type functions such as ref, length and
append should be prefixed by nothing for the
list version, "string-" for the string version,
and "vector-" for the vector version.
The first stance is preferable because of the symmetry, the second
because the names for the list versions (probably the most commonly
used) are shorter. I think that the first stance is less confusing
and less likely to cause trouble.
Cheers,
Kent Dybvig
∂15-Jan-85 1914 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa Re: Scheme String Operations: the Report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 15 Jan 85 19:14:04 PST
Received: from ti-csl by csnet-relay.csnet id ab07537; 15 Jan 85 22:01 EST
Date: 15 Jan 1985 1445-CST
From: David Bartley <Bartley%ti-csl.csnet@csnet-relay.arpa>
Subject: Re: Scheme String Operations: the Report
To: CPH%MIT-OZ@mit-mc.ARPA, Bartley%ti-csl.csnet@csnet-relay.arpa,
Jensen%ti-csl.csnet@csnet-relay.arpa, Oxley%ti-csl.csnet@csnet-relay.arpa,
Scheme@mit-mc.ARPA
cc: Bartley%ti-csl.csnet@csnet-relay.arpa
In-Reply-To: Your message of 14-Jan-85 0529-CST
Received: from csl60 by ti-csl; Tue, 15 Jan 85 20:45 CST
Chris,
Thanks for mailing out the preliminary report on your proposal for string
operations for Scheme. Here are my initial reactions.
-- You were clearly influenced by Common LISP (CL), since at least 27 of
your functions have direct analogues in CL. You rarely use the same name
as CL uses, however. I tend to agree with most of your name choices, with
one exception: CL uses the suffixes =, <, etc. for case sensitive
comparisons of characters and strings and the suffixes EQUAL, LESSP, etc
for case-insensitive comparisons. I prefer to adopt that convention rather
than inventing the suffix -CI.
We should definitely preserve our conventions regarding suffixed ? and !
characters. Thus, CL's CHAR-LESSP and NSTRING-UPCASE should be renamed
CHAR-LESS? and STRING-UPCASE! for Scheme.
-- We probably need a (CHAR? obj) predicate. The following are useful;
can we agree on their meaning?
(CHAR->INTEGER char) ; CL's CHAR-CODE ?
(INTEGER->CHAR n) ; CL's CODE-CHAR ?
-- The order of arguments to CHAR-SET-MEMBER? is reversed from that of
MEMBER, MEMV, and MEMQ.
-- How is a CHAR-SET represented? Created? Modified?
-- Why distinguish STRING-ALLOCATE from MAKE-STRING? By analogy with
MAKE-VECTOR, shouldn't MAKE-STRING take the second argument optionally?
-- May I assume that string and character values are printed (and read)
as defined by CL?
-- May I assume that all of the operations you defined are procedures,
not special forms?
-- May I assume that SUBSTRING and other names written without ! always
return a copy rather than sharing structure?
-- One way to reduce the number of operations is to combine the STRING-
and SUBSTRING- operations by accepting optional substring operands. For
example, specify only
(STRING-FILL! string char { start { end }} )
instead of
(STRING-FILL! string char) and
and (SUBSTRING-FILL! string start end char)
Note that the <char> argument has been repositioned.
It would be useful to let either <start> or <end> default. In the example
above, we could interpret
(STRING-FILL! string char start)
as filling from <start> to the end of the string.
-- What should happen when indexes cross (start>end) or go outside the
proper range?
-- Are you suggesting that the Basic Character Operations, Basic String
Operations, and Standard Operations be 'required' and the rest be
'optional'? If not, where would you draw the line? Do you use all of
these operations yourself?
-- Is the character datatype in MIT Scheme extended the same way CL has
gone? Do you support font and/or bit info? Have you added operations to
MIT Scheme beyond those you've proposed in your report?
-- In summary, the proposal looks sound and I have no arguments with the
functionality you are proposing. I'll pass on further comments after we've
had time to digest it more thoroughly.
Regards,
David Bartley
-------
∂15-Jan-85 2339 @MIT-MC:CPH@MIT-OZ Scheme String Operations: the Report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 15 Jan 85 23:38:57 PST
Date: Wed, 16 Jan 1985 02:40 EST
Message-ID: <CPH.12079941473.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Cc: Jensen%ti-csl.csnet@CSNET-RELAY.ARPA,
Oxley%ti-csl.csnet@CSNET-RELAY.ARPA, Scheme@MIT-MC.ARPA
Subject: Scheme String Operations: the Report
In-reply-to: Msg of 15 Jan 1985 15:45-EST from David Bartley <Bartley%ti-csl.csnet at csnet-relay.arpa>
Date: Tuesday, 15 January 1985 15:45-EST
From: David Bartley <Bartley%ti-csl.csnet at csnet-relay.arpa>
-- We probably need a (CHAR? obj) predicate. The following are useful;
can we agree on their meaning?
(CHAR->INTEGER char) ; CL's CHAR-CODE ?
(INTEGER->CHAR n) ; CL's CODE-CHAR ?
-- How is a CHAR-SET represented? Created? Modified?
-- Is the character datatype in MIT Scheme extended the same way CL has
gone? Do you support font and/or bit info? Have you added operations to
MIT Scheme beyond those you've proposed in your report?
In answer to all of these: I purposefully limited my description of
characters (and character sets) to that minimum required to describe
the string abstraction. I did this because I felt that the string
abstraction was very largely independent of the character abstraction;
this method shows the dependence pretty clearly.
Further, I recall that we agreed to do characters "the CL way" at the
workshop, at least so far as syntax. My character datatype is heavily
influenced by CL, and implements bits but not fonts (I don't need them
now). I would be willing to discuss both this and the character set
abstraction if there is interest.
-- You were clearly influenced by Common LISP (CL)...
Not so! The string operations were mostly designed from scratch; I
was unaware that they were so similar.
...CL uses the suffixes =, <, etc. for case sensitive
comparisons of characters and strings and the suffixes EQUAL, LESSP, etc
for case-insensitive comparisons. I prefer to adopt that convention...
Mumble. I don't particularly like those names, but then, I don't
particularly care about the names anyway. I'm not terribly happy with
the names I chose, either. Whatever folks like is fine with me.
-- May I assume that string and character values are printed (and read)
as defined by CL?
Yes; I think that we agreed upon this at the workshop.
-- May I assume that all of the operations you defined are procedures,
not special forms?
Yes!!! (with feeling)
-- May I assume that SUBSTRING and other names written without ! always
return a copy rather than sharing structure?
Yes. Furthermore, operations written with a "!" return undefined values.
-- Why distinguish STRING-ALLOCATE from MAKE-STRING? By analogy with
MAKE-VECTOR, shouldn't MAKE-STRING take the second argument optionally?
-- One way to reduce the number of operations is to combine the STRING-
and SUBSTRING- operations by accepting optional substring operands.
Gee, I guess that I don't feel too good about that. While it is true
that this cuts down on the number of names, I have an irrational fear
of widespread optionalogy. Perhaps it is from overexposure to
flagrant misuse, but I prefer not to use optionals at the "lower
levels" of my code.
Also, I was particularly thinking about the workshop, and I recall
there was very mixed feeling about optional arguments, rest arguments,
etc... I felt that this would be more acceptable to the community as a
whole.
-- The order of arguments to CHAR-SET-MEMBER? is reversed from that of
MEMBER, MEMV, and MEMQ.
Hmm... This was chosen to match other stuff... in particular,
VECTOR-REF, LIST-REF, etc. The convention is: the compound structure
first, the key second. In hindsight, it clearly should match MEMfoo.
-- What should happen when indexes cross (start>end) or go outside the
proper range?
Sorry, I should have spelled that out. It will signal an error, in
all cases (although maybe not at the most reasonable place, in my
implementation). I specific: everywhere where I have described the
arguments as "a string", "a character", "a substring", etc., those can
be construed as requirements. Errors will happen if those things are
not true.
-- Are you suggesting that the Basic Character Operations, Basic String
Operations, and Standard Operations be 'required' and the rest be
'optional'? If not, where would you draw the line? Do you use all of
these operations yourself?
No, I was making no such suggestion; I would be hesitant to do so
without some discussion. I do feel that the 'Basic String Operations'
and 'Standard Operations', with the exception of STRING-ALLOCATE,
STRING-SET!, and STRING-FILL!, are very useful, and perhaps should be
required. But then we have already agreed upon those in the 'Basic'
category, and I think that there would be little disagreement about
the 'Standard' ones.
But I can't really say where one should draw the line; all of these
procedures are useful if one ever does anything even moderately hairy.
Personally, I have used most of these operations pretty freely in the
editor.
I have found, though, that a particular pattern has emerged. The
mutating operations are used (in conjunction with STRING-ALLOCATE)
almost exclusively for the construction of higher level, non-mutating
operations like SUBSTRING and STRING-APPEND. I think that such things
might safely be relegated to the realm of 'system programming', for
those who prefer to make such a distinction.
Anyway, if there is interest in working out the boundaries of
'required' vs. 'optional' here, I am perfectly willing to add more of
my flame to the conflagration.
∂24-Jan-85 1227 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa Purpose of a "common" Scheme
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 24 Jan 85 12:00:43 PST
Received: from indiana by csnet-relay.csnet id aa09096; 24 Jan 85 14:38 EST
Date: Thu, 24 Jan 85 13:27:13 est
From: Will Clinger <willc%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA11826; Thu, 24 Jan 85 13:27:13 est
To: scheme@mit-mc.ARPA
Subject: Purpose of a "common" Scheme
Surely different people have different purposes in wanting a more
standardized Scheme. Half the fun is getting everyone to work
together and to agree. It helps to be vague about the purposes.
Here's my view, from a draft introduction to the final report on
the workshop:
Scheme shares with Common Lisp [\ref] the goal of a core
language common to several implementations. Scheme differs
from Common Lisp in that the purpose of the common language
has more to do with porting ideas than with porting code.
It is appropriate therefore that Scheme is much smaller, is
less pervasively specified, and will evolve faster than
Common Lisp.
Let me know by direct mail if you object to that wording.
William Clinger (willc@indiana)
∂31-Jan-85 0921 @MIT-MC:mw%brandeis.csnet@csnet-relay.arpa Resources for Scheme course
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 31 Jan 85 09:17:38 PST
Received: from brandeis by csnet-relay.csnet id a002562; 31 Jan 85 12:13 EST
Received: by brandeis.ARPA (4.12/4.7)
id AA14346; Thu, 31 Jan 85 10:14:16 est
Date: 31 Jan 1985 09:53-EST
From: mw%brandeis.csnet@csnet-relay.arpa
In-Real-Life: Mitchell Wand,faculty
Subject: Resources for Scheme course
To: scheme@mit-mc.ARPA, cth%indiana.csnet@csnet-relay.arpa
Cc: jc%brandeis.csnet@csnet-relay.arpa
Message-Id: <476031183/mw@brandeis>
Brandeis is currently considering creating a laboratory facility for a
course on the style of the Abelson & Sussman book. For this purpose, I
am collecting data on the state of various workstation implementations
of Scheme and related languages (e.g. T). I know about some
implementations, but I'd like to hear about others, and get up-to-date
information even about the ones I've heard of. In particular:
1) What workstations would you recommend for such an undertaking, and
what is the availability of appropriate software?
2) What ratio of students/workstation would you recommend? To give
some idea of the planned intensity of the course, let's assume that we
plan to cover about half of the material in A&S in a semester.
3) How many square feet per workstation should we plan on? What other
things in the physical arrangment of the facility should we watch out
for?
Reply to mw@brandeis on csnet. I will post a summary of replies to
the mailing list if interest warrants. Thanks for your help.
-- Mitch Wand
∂01-Feb-85 0930 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa quotient, remainder, letrec
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 1 Feb 85 09:30:03 PST
Received: from indiana by csnet-relay.csnet id aa04954; 1 Feb 85 12:23 EST
Date: Fri, 1 Feb 85 11:13:53 est
From: Will Clinger <willc%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA02926; Fri, 1 Feb 85 11:13:53 est
To: scheme@mit-mc.ARPA
Subject: quotient, remainder, letrec
In the preliminary report on the Brandeis workshop, I said that quotient and
remainder were such that if x, y, q, and r are integers such that x = qy +
r, y is nonzero, r has the same sign as y and has absolute value less than
that of y, then (quotient x y) was q and (remainder x y) was r. Since that
conflicts with Common Lisp, Franz Lisp, T, Scheme 84, Scheme 312, and maybe
MIT Scheme (my documentation on MIT Scheme isn't clear on the issue), I
retract that definition in favor of:
If x, y, q, and r are integers such that x = qy + r, y is nonzero, r has the
same sign as x, and |r| < |y|, then (quotient x y) is q and
(remainder x y) is r.
The definition of letrec in the preliminary report is wrong.
William Clinger
willc@indiana
∂02-Feb-85 1040 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa Scheme String Operations
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 2 Feb 85 10:39:59 PST
Received: from ti-csl by csnet-relay.csnet id ah03968; 2 Feb 85 10:36 EST
Date: 1 Feb 1985 1453-CST
From: David Bartley <Bartley%ti-csl.csnet@csnet-relay.arpa>
Subject: Scheme String Operations
To: Scheme@mit-mc.ARPA, CPH%MIT-OZ@mit-mc.ARPA
cc: SCHEME.Users%ti-csl.csnet@csnet-relay.arpa,
Bartley%ti-csl.csnet@csnet-relay.arpa
Received: from csl60 by ti-csl; Fri, 1 Feb 85 16:57 CST
We at Texas Instruments propose the following revisions to Chris Hanson's
preliminary report on Scheme string operations. Our implementation has
already begun, so we would like to hear objections and other comments as
soon as possible. Thanks!
1. Name changes
For reasonable consistency with Common LISP, we propose the following
name changes:
Preliminary report Our proposal Common LISP
================== ============ ===========
char-equal? char= char=
char-equal-ci? char-equal? char-equal
char-less? char< char<
char-less-ci? char-less? char-lessp
substring-equal? substring=
string-equal? string=
substring-equal-ci? substring-equal?
string-equal-ci? string-equal?
substring-less? substring<
string-less? string<
substring-less-ci? substring-less?
string-less-ci? string-less?
2. Added features
(CHAR? obj) is needed for argument checking, if nothing else.
We agreed at the workshop to include SYMBOL->STRING and STRING->SYMBOL
as essential and STRING->UNINTERNED-SYMBOL as optional.
3. Changes
CHAR-SET-MEMBER should take its arguments in the same order as MEMBER.
4. Essential features
We are not sure how to separate ``essential'' from ``optional''
features, but will probably go with everything labeled ``minimal'' below.
Those labeled ``elective'' will be available but not part of the initial
load of the system.
Basic Character Operations
minimal: CHAR?, CHAR=, CHAR-EQUAL?, CHAR<, CHAR-LESS?,
CHAR-UPCASE, CHAR-DOWNCASE
elective: CHAR-UPPER-CASE?, CHAR-LOWER-CASE?, CHAR-SET-MEMBER?
Basic String Operations
minimal: STRING?, STRING-LENGTH, STRING-REF, STRING-SET!,
STRING->SYMBOL, STRING->UNINTERNED-SYMBOL, SYMBOL->STRING
elective: STRING-ALLOCATE
Standard Operations
minimal: MAKE-STRING, STRING-FILL!, STRING-NULL?, SUBSTRING,
STRING-APPEND, STRING-COPY, STRING->LIST, LIST->STRING
Motion Primitives
minimal: SUBSTRING-FILL!, SUBSTRING-MOVE-RIGHT!, SUBSTRING-MOVE-LEFT!
Comparison Primitives
minimal: SUBSTRING=, STRING=, SUBSTRING-EQUAL?, STRING-EQUAL?,
SUBSTRING<, STRING<, SUBSTRING-LESS?, STRING-LESS?
elective: SUBSTRING-MATCH-FORWARD, STRING-MATCH-FORWARD,
SUBSTRING-MATCH-FORWARD-CI, STRING-MATCH-FORWARD-CI,
SUBSTRING-MATCH-BACKWARD, STRING-MATCH-BACKWARD,
SUBSTRING-MATCH-BACKWARD-CI, STRING-MATCH-BACKWARD-CI
Character Search Primitives
elective: all
Case
elective: all
-- Regards,
David Bartley
-------
∂03-Feb-85 1055 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Re: Scheme String Operations
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 3 Feb 85 10:55:37 PST
Received: from unc by csnet-relay.csnet id aa08903; 3 Feb 85 13:47 EST
Received: by unc (4.12/4.7) id AA06699; Sun, 3 Feb 85 11:59:27 est
Date: Sun, 3 Feb 85 11:59:27 est
From: Kent Dybvig <dyb%unc.csnet@csnet-relay.arpa>
Message-Id: <8502031659.AA06699@unc>
To: scheme@mit-mc.ARPA
Subject: Re: Scheme String Operations
1. I prefer Chris Hanson's names over the Common Lisp or Bartley names.
I find the CL names confusing and nonsensical. Why does "char=" imply
case sensitivity, and "char-equal" insensitivity? The issue is also
confused because CL does not define "equal" to use "char-equal" as is
implied by the naming convention.
I have been using Common Lisp for over a year since helping to bring
Data General's system into existence. Many of us get confused about
which is which. There would be no confusion with a suffix such as
"-ci". Except for possible commercial interests, I can see no benefit
in copying the mistakes of Common Lisp.
2. I would rather spell out the name "character" in all functions rather
than use the shorter "char" but that's probably too much to ask.
3. I wish there weren't so many string functions. I think Chris Hanson
was on the right track with the very primitive set that can be used to
construct all the others. Perhaps we should have that set plus
"string-ref", "string-equal?", "string-less?" "string-equal-ci?",
and "string-less-ci?", "string->list", and "list->string".
4. I have a "string" function in my system that comes in handy --
(string char1 char2 ... charN) => string of char1 ... charN, N >= 0.
For example:
(string #\a #\b #\c) => "abc".
This is easy to write as (lambda x (list->string x)).
It is particularly useful when creating a cursor-addressing string to
send to the tty.
5. I do not view "string->symbol" and "symbol->string" as string functions.
They are symbol creation and destructuring primitives. In fact, I
strongly object to the names since they are not analogous to other
type-conversion functions such as "string->list" and "character->integer".
I'll say more about this in a separate note.
6. As far as optionality is concerned, I would like to see Scheme adopt
an optional argument mechanism. It reduces the namespace and is really
quite easy to implement efficiently. A function like "member" becomes
completely general, allowing not only "eq?", "eqv?" and "equal?" tests
but also any user-defined test. However, until we have optional
arguments that can be defined using a lambda expression, I do not
think we should have primitives with optional arguments. Either the
language has them or it doesn't.
Kent Dybvig
decvax!mcnc!unc!dyb
dyb.unc@Csnet-Relay
∂03-Feb-85 1059 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa string->symbol, symbol->string
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 3 Feb 85 10:57:50 PST
Received: from unc by csnet-relay.csnet id ab08903; 3 Feb 85 13:47 EST
Received: by unc (4.12/4.7) id AA06730; Sun, 3 Feb 85 12:00:27 est
Date: Sun, 3 Feb 85 12:00:27 est
From: Kent Dybvig <dyb%unc.csnet@csnet-relay.arpa>
Message-Id: <8502031700.AA06730@unc>
To: scheme@mit-mc.ARPA
Subject: string->symbol, symbol->string
"symbol->string" and "string->symbol functions are not analogous to
"list->string" or "string->list".
"list->string" converts the same data from one representation into
another, with no loss of information. The same is true for "string->list",
"list->vector", "vector->list" and "character->integer".
A symbol is more than just an alternate representation for a string.
It can be an identifier or keyword. Some implementations allow symbols
to have property lists. All of this information is lost in the conversion
from symbol to string, some is regained in the opposite conversion.
I tend to think of the name of a symbol as an attribute of that symbol.
"symbol->string" is more correctly called "symbol-name".
Furthermore, whereas one can expect "string->list" to return a new list
made up of unique cons-cells, "string->symbol" may return an existing
symbol. The name "intern" is more appropriate for this functionality.
(Perhaps "hash-make-symbol" would be a better name.)
If making a unique, uninterned symbol is supported, the name "make-symbol"
is appropriate.
If what we are really doing when we say "make-symbol" or "string->symbol"
was changing representations, then "string->symbol" would be fine. But
it isn't a type conversion we are doing, it's symbol creation (or lookup).
It seems analogous to saying "make-vector" should be called "integer->vector"
because we are taking an integer, n, and returning a vector of length n.
The name is only one aspect of a symbol in much the same way that the length
is only one aspect of a vector.
Kent Dybvig
decvax!mcnc!unc!dyb
dyb.unc@Csnet-Relay
∂04-Feb-85 0221 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Chez Scheme
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 4 Feb 85 02:21:10 PST
Received: from unc by csnet-relay.csnet id aa11924; 4 Feb 85 5:13 EST
Received: by unc (4.12/4.7) id AA00752; Mon, 4 Feb 85 00:29:49 est
Date: Mon, 4 Feb 85 00:29:49 est
From: Kent Dybvig <dyb%unc.csnet@csnet-relay.arpa>
Message-Id: <8502040529.AA00752@unc>
To: Scheme@mit-mc.ARPA
Subject: Chez Scheme
=> Chez Scheme
Chez Scheme is an implementation of Scheme for Vaxes
running 4.2 Bsd Unix. Chez Scheme supports all required and
most optional features of the anticipated Scheme standard.
The first Chez Scheme release will include an extensive
reference manual. A Chez Scheme tutorial is in preparation
for later releases.
Features of Scheme:
o Clean, concise dialect of Lisp
o Lexically scoped (as is Common Lisp)
o Full function closures (first-class, full funarg)
o Tail-recursion reliably translated into iteration
o Full upward/downward continuations
Features of Chez Scheme:
o Incremental native-code (Vax object code) compiler
o Flexible user interface
o Fast-loading compiled files
o Very fast arbitrary precision integer and rational
arithmetic
o Programmable exception handlers
o Support for multi-tasking (timer interrupts,
continuations)
o String and vector operations
o Macros and structures
o Engines (a process abstraction)
Application programs distributed with the first release
of Chez Scheme include a set operation package, a logic
programming subsystem, a lazy-cons facility, and a generic
matrix, vector and scalar multiplication package.
Faster than many Lisp systems, Chez Scheme may be the
fastest Scheme available. On the Vax 11/780, Chez Scheme is
competitive with benchmarks reported for Franz Lisp and
Digital Common Lisp at last summer's AAAI conference in
Austin, TX. For example, Chez Scheme runs the "Tak"
benchmark in 3.4 cpu seconds and the "Deriv" benchmark in
21.9 cpu seconds. The code tested contained no
declarations, used generic arithmetic, and had no inlined
calls. No separate compilation phase is necessary: all code
loaded into Chez Scheme is compiled incrementally.
Chez Scheme is available for mid-March distribution to
US educational institutions only. We will send a license
agreement to interested parties. There is a $400
distribution fee. We are not yet able to do foreign or
commercial distributions, but contact us if you are
interested.
Write for a copy of the license agreement and ordering
information to:
R. Kent Dybvig
Department of Computer Science
New West Hall (035-A)
University of North Carolina
Chapel Hill, NC 27514
USA
decvax!mcnc!unc!dyb (usenet)
dyb.unc@Csnet-Relay (ARPANET)
∂05-Feb-85 1002 JAR@MIT-MC string->symbol, symbol->string
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 5 Feb 85 10:02:15 PST
Date: 5 February 1985 13:03-EST
From: Jonathan A Rees <JAR @ MIT-MC>
Subject: string->symbol, symbol->string
To: dyb%unc.csnet @ CSNET-RELAY
cc: SCHEME @ MIT-MC
In-reply-to: Msg of Sun 3 Feb 85 12:00:27 est from Kent Dybvig <dyb%unc.csnet at csnet-relay.arpa>
Date: Sun, 3 Feb 85 12:00:27 est
From: Kent Dybvig <dyb%unc.csnet at csnet-relay.arpa>
"symbol->string" and "string->symbol functions are not analogous to
"list->string" or "string->list".
"list->string" converts the same data from one representation into
another, with no loss of information. The same is true for "string->list",
"list->vector", "vector->list" and "character->integer".
There definitely is loss of information in list->vector and friends; you
lose eq-ness and location identity. (vector->list (list->vector l))
gives a copy of the list, so rplacas and rplacds will affect different
cells.
A symbol is more than just an alternate representation for a string.
It can be an identifier or keyword. Some implementations allow symbols
to have property lists. All of this information is lost in the conversion
from symbol to string, some is regained in the opposite conversion.
I tend to think of the name of a symbol as an attribute of that symbol.
"symbol->string" is more correctly called "symbol-name".
How do symbols differ from numbers, which can also be identifiers or
"keywords," in this regard? The way I look at things, all associations
of information with symbols are through tables not intimately tied to
the symbol itself. To say that symbols "have" values is like saying
that integers "have" values - getting a value out of an environment,
given a symbol, is completely analogous to getting a value out of a
vector, given an integer. "Essential scheme" intentionally doesn't have
property lists. Symbol eq-ness is global, so property lists would
violate the desire (based on modularity considerations) to avoid global
state; and given reasonable association tables, they are unnecessary.
Furthermore, whereas one can expect "string->list" to return a new list
made up of unique cons-cells, "string->symbol" may return an existing
symbol. The name "intern" is more appropriate for this functionality.
(Perhaps "hash-make-symbol" would be a better name.)
But character->integer (or char->ascii or whatever you want to call it)
may return an existing integer. What is the difference? Since symbols
are immutable objects, like numbers, it's okay that an existing one is
returned.
Reference to hashing doesn't seem very abstract to me...
If making a unique, uninterned symbol is supported, the name "make-symbol"
is appropriate.
I personally don't believe in uninterned symbols (yet?), but if they
existed then make-symbol would be an okay name, maybe better than
string->uninterned-symbol, but I don't much care.
I think that the "->" convention shouldn't have such a terribly strict
meaning. I guess it's my feeling that string->symbol and symbol->string
are acceptable even if they aren't strictly analogous to list->vector
and vector->list.
Jonathan Rees (JAR@MC)
∂05-Feb-85 1007 JAR@MIT-MC Scheme String Operations
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 5 Feb 85 10:06:52 PST
Date: 5 February 1985 13:08-EST
From: Jonathan A Rees <JAR @ MIT-MC>
Subject: Scheme String Operations
To: SCHEME @ MIT-MC
In-reply-to: Msg of Sun 3 Feb 85 11:59:27 est from Kent Dybvig <dyb%unc.csnet at csnet-relay.arpa>
I should point out that there were people at the workshop who felt
strongly that strings should not be mutable. I don't much care one way
or the other. If the things which use the "..." syntax are immutable
then there ought to be such a thing as vector-of-character; also, if
strings are immutable then it's not clear how they are different from
symbols (maybe just that they self-evaluate). But those of you who
strongly think (or thought) that strings should be immutable should
speak up.
Jonathan
∂21-Feb-85 1259 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa Draft delayed to 15 March
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Feb 85 12:59:45 PST
Received: from indiana by csnet-relay.csnet id ad22218; 21 Feb 85 15:20 EST
Date: Thu, 21 Feb 85 13:14:25 est
From: Will Clinger <willc%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA04423; Thu, 21 Feb 85 13:14:25 est
To: scheme@mit-mc.ARPA
Subject: Draft delayed to 15 March
The draft of the final report on the Brandeis workshop, which was to have
come out around 1 March, will be delayed to the vicinity of 15 March.
I will be travelling until 4 March and probably won't be able to finish
the draft until I get back. I am sorry for the delay.
William Clinger
Indiana University
∂10-Mar-85 1716 @MIT-MC:GJS@MIT-EECS Numbers Committee Report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 10 Mar 85 17:16:24 PST
Received: from MIT-EECS by MIT-MC via Chaosnet; 10 MAR 85 16:53:21 EST
Date: Sun 10 Mar 85 16:53:46-EST
From: GJS%MIT-EECS@MIT-MC.ARPA
Subject: Numbers Committee Report
To: scheme@MIT-MC
Sorry it took so long, but I was afraid to do a half-assed job. The following
report raises 10↑10 issues which should be thought about by all of us. I
believe (after a bit of study) that other language people have been
inadequately careful about the status of numbers in their languages. Numbers
are probably the most complicated data structures we ever deal with, so we must
try to do a good job on them.
The report is entirely the responsibility of GJS (so throw stones at him),
though Bill Rozas, Jon Rees, Guy Steele, Chris Hanson, Hal Abelson, Yekta
Gursel, and Chris Lindblad have made significant contributions -- most of
their stones have been thrown and absorbed (some hurt!).
Scheme Numbers
Intent
Numerical computation has traditionally been neglected by the Lisp
community. Until Common Lisp there has been no carefully thought out
strategy for organizing numerical computation; and with the exception
of the MacLisp system there has been little effort to efficiently
execute numerical code. We applaud the excellent work of the Common
Lisp committee and we accept many of their recommendations. In some
ways we simplify and generalize their proposals in a manner consistent
with the purposes of Scheme.
Scheme numerical operations treat numbers as abstract data, as
independent of the machine representation as is possible. Thus, the
casual user should be able to write simple programs without having to
know that the implementation may use fixed-point, floating-point, and
perhaps other representations for his data. Unfortunately, this
illusion of uniformity can only be sustained approximately -- the
implementation of numbers will leak out of our abstraction whenever
the user must be in control of precision, or accuracy, or when he must
construct especially efficient computations. Thus we also must
provide escape mechanisms so that a sophisticated programmer can
exercise more control of the execution of his code and the
representation of his data when it is essential to do so.
We separate out several apparently related issues of representation --
the abstract numbers, their machine representation, and the
input/output formats of the symbolic expressions which denote
numerical constants. We will use mathematical words such as NUMBER,
COMPLEX, REAL, RATIONAL, and INTEGER for properties of the abstract
numbers, data-structure names such as FIXNUM, BIGNUM, RATNUM, and
FLONUM for machine representations, and names like INT, FIX, FLO, SCI,
RAT, POLAR, and RECT for input/output formats.
Numbers
A Scheme system provides data of type NUMBER, which is the most
general numerical type supported by that system. NUMBER is likely to
be a complicated union type implemented in terms of FIXNUMs, BIGNUMS,
FLONUMS, etc. but this should not be apparent to a naive user. What
the user sees is that the obvious operations on numbers produce the
mathematically expected results, within the limits of the
implementation. Thus if the user divides 3 by 2, he should get
something like 1.5 (or, the exact fraction 3/2). If he adds that
result to itself, and if the implementation can swing it, he should
get an exact 3.
!
Mathematically, numbers may be arranged into a tower of subtypes with
natural projections and injections relating adjacent members of the
tower:
NUMBER
COMPLEX
REAL
RATIONAL
INTEGER
We impose a uniform rule of downward coercion -- a number of one type
is also of a lower type if the injection (up) of the projection (down)
of a number leaves the number unchanged. Since this tower is a real
mathematical entity, Scheme provides predicates and procedures that
access the tower.
Not all Scheme implementations must provide the whole tower, but they
are required to implement a coherent subset, consistent with the
purposes of Scheme.
Exactness
Numbers are either EXACT or INEXACT. A number is exact if it was
derived from EXACT numbers using only EXACT operations. A number is
INEXACT if it models a quantity known only approximately, if it was
derived using INEXACT ingredients, or if it was derived using INEXACT
operations. Thus INEXACTness is a contagious property of a number.
Some operations, such as the square root (of non-square numbers) must
be INEXACT because of the finite precision of our representations.
Other operations are inexact because of implementation requirements.
We emphasize that exactness is independent of the position of the
number on the tower. It is perfectly possible to have an INEXACT
INTEGER or an EXACT REAL; 355/113 may be an EXACT RATIONAL or it may
be an INEXACT RATIONAL approximation to pi, depending on the
application.
Operationally, it is the system's responsibility to combine EXACT
numbers using exact methods, such as infinite precision integer and
rational arithmetic, where possible. An implementation may not be
able to do this (if it does not use infinite precision integers and
rationals), but if a number becomes inexact for implementation reasons
there is probably an important error condition, such as integer
overflow, to be reported. Arithmetic on INEXACT numbers is not so
constrained. The system may use floating point and other flaky
representation strategies for INEXACT numbers. This is not to say
that implementors need not use the best known algorithms for INEXACT
computations -- only that high-quality approximate methods are
allowed. In a system which cannot explicitly distinguish exact from inexact numbers the system must do its best to
maintain precision. Scheme systems must not burden users with
numerical operations described in terms of hardware and
operating-system dependent representations such as FIXNUM and FLONUM.
These representation issues should not be germane to the user's
problems.
!
We highly recommend that the IEEE 32-bit and 64-bit floating-point
standards be adopted for implementations that use floating-point
internal representations. To minimize loss of precision we adopt the
following rules: If an implementation uses several different size
floating-point formats, the results of any operation with a
floating-point result must be expressed in the largest format used to
express any of the floating-point arguments to that operation. It is
desirable (but not required) for potentially irrational operations
such as SQRT, when applied to EXACT arguments, to produce EXACT
answers when that is possible (eg. sqrt[4]=2, exactly). If an EXACT
number (or an INEXACT number represented as a FIXNUM, a BIGNUM, or a
RATNUM) is operated upon so as to produce an INEXACT result (as by
SQRT), then if the result is represented as a FLONUM, then the largest
available format FLONUM must be used; but if the result is expressed
as a RATNUM then the rational approximation must have at least as much
precision as the largest available format FLONUM. (Note that this
last rule is much stronger than that used in Common Lisp. Consider
the result of the square root of a rational, for example.)
Numerical Operations
Scheme provides the usual set of operations for manipulation of
numbers. In the specification below we illustrate each built in
numerical operation with an expression using the default operator
symbol which is bound to that operation in the global environment. In
general, numerical operations require numerical arguments. We use the
following symbols to represent the various types of object in our
descriptions. It is an error for an operation to be presented with an
argument that it is not specified to handle.
obj any arbitrary object
z, z1, ... zi, ... {complex, real, rational, integer} x,
x1, ... xi, ... {real, rational, integer}
q, q1, ... qi, ... {rational, integer} n, n1, ... ni, ...
{integer}
In our descriptions some arguments are required and others are
optionally allowed. For example, numerical comparisons are allowed to
have any number of arguments, but they must have at least two. We
indicate this by putting in explicit argument symbols for each
required argument and a "..." indicating the rest.
!
A. Numerical type predicates can be applied to any kind of argument.
They return true if the object is of the named type. In general, if a
type predicate is true of a number then all higher type predicates are
also true of that number. Not every system supports all of these
types. It is entirely possible to have a Scheme system which only has
INTEGERs, however, it must have all of these predicates.
(NUMBER? obj) (COMPLEX? obj) (REAL? obj) (RATIONAL? obj) (INTEGER?
obj)
B. Numerical predicates test a number for a particular property.
They return a boolean value.
(ZERO? z) (POSITIVE? x) (NEGATIVE? x) (ODD? n) (EVEN? n)
(EXACT? z) (INEXACT? z)
C. Numerical comparisons require all of their arguments to be
numbers. They optionally take many arguments, as in Common Lisp, to
facilitate encoding of range checks. Not all implementations support
this extension. These predicates have redundant names (with and
without the terminal "?") to make all populations happy. Warning: On
INEXACT numbers equality tests will give unreliable results; other
numerical comparisons are only heuristically useful (ask a numerical
analyst about this!)
(= z1 z2 ... zi) all arguments are numerically equal
(=? z1 z2 ... zi)
(< x1 x2 ... xi) arguments are monotonically increasing
(<? x1 x2 ... xi)
(> x1 x2 ... xi) arguments are monotonically decreasing
(>? x1 x2 ... xi)
(<= x1 x2 ... xi) arguments are monotonically nondecreasing
(<=? x1 x2 ... xi)
(>= x1 x2 ... xi) arguments are monotonically nonincreasing
(>=? x1 x2 ... xi)
(max x1 ... xi)
(min x1 ... xi)
!
D. Arithmetic operations require all arguments to be numbers.
Generalization to arbitrary numbers of arguments is implementation
dependent.
(+ z1 ... zi) ==> z1 + ... + zi
(+ z) ==> z
(+) ==> 0 (the identity)
(* z1 ... zi) ==> z1 * ... * zi
(* z) ==> z
(*) ==> 1 (the identity)
(- z1 ... zi) ==> z1 - z2 - ... - zi
(- z) ==> -n
(/ z1 ... zi) ==> z1 / z2 / ... / zi
(/ z) ==> 1/z
(-1+ z) ==> -1 + z
(1+ z) ==> 1 + z
(abs z)
E. Integer division operations are only defined on integers.
(quotient n1 n2) ==> n3
(remainder n1 n2) ==> n4
(modulo n1 n2) ==> n4
In general, these are intended to implement number-theoretic division,
where for positive arguments, n1 and n2
n1 = n3*n2 + n4 and 0 <= n4 < d.
REMAINDER and MODULO differ on negative arguments as in the Common
Lisp REM and MOD procedures -- the remainder always has the sign of
the dividend, the modulo always has the sign of the divisor:
(modulo 13 4) ==> 1 (remainder 13 4) ==> 1
(modulo -13 4) ==> 3 (remainder -13 4) ==> -1
(modulo 13 -4) ==> -3 (remainder 13 -4) ==> 1
(modulo -13 -4) ==> -1 (remainder -13 -4) ==> -1
F. The following procedures are also only defined on integers. The
result is always non-negative.
(gcd n1 ... ni) Greatest common divisor
(gcd) ==> 0 (the identity)
(lcm n1 ... ni) Least common multiple
(lcm) ==> 1 (the identity)
!
G. Integers and rationals can be made using the following procedures.
Note, this does not make the answer EXACT -- in fact, the resulting
number is clearly INEXACT, it can be made EXACT with an exactness
coercion.
(floor x) The largest integer not larger than x
(ceiling x) The smallest integer not smaller than x
(truncate x) The integer of maximal absolute value not larger than x
(round x) The closest integer to n. Rounds to even when halfway.
(rationalize x y) Produces the best rational approximation to x
within the tolerance specified by y.
(rationalize x) Produces the best rational approximation to x,
preserving all of the precision in its
representation.
H. In implementations which support real numbers the following are
defined to conform with the Common Lisp standard as to meaning (be
careful of the branch cuts if complex numbers are allowed).
(exp z) (log z) (expt z1 z2) (sqrt z)
(sin z) (cos z) (tan z) (asin z) (acos z) (atan z1 z2)
I. In implementations which support complex numbers we also provide
(make-rectangular x1 x2) ==> x1 + x2i
(make-polar x3 x4) ==> x3*e↑x4i
(real-part z) (imag-part z) (magnitude z) (angle z)
J. Exactness coercions.
(exact->inexact z) Makes an inexact representation of z.
Pretty harmless.
(inexact->exact z) Makes an exact representation of z.
I hope you know what you are doing here!
K. Type-restricted operations are useful for error checking, or as
advice to a compiler. Scheme optionally supplies such type-restricted
operations: If op is defined on objects of numerical type, t1, and if
t2 is any type lower on the tower than t1, then (t2 op) is the
restricted operator for objects of type t2. For example, the
following are expressions using restricted operators:
((real sqrt) 5) ; Gets the right thing.
((real sqrt) -1) ; Will signal an error.
((integer sqrt) 10) ; Will signal an error -- You probably
wanted to compute (truncate ((real sqrt) 10))
!
For completeness, the system also supplies the most general operations
((number +) 3 4)
The default operations, initially bound to the customary operators in
the global environment, are these most general operations. The
type-restriction procedures REAL, INTEGER, ... are simple maps which
map the default operations to their restricted cousins.
Some systems may want to enhance this facility, to allow integer
subranges or other mathematically meaningful restrictions such as
modular arithmetic, for example:
(((integer-subrange 3 5) +) 2 3 4) ;Will signal an error.
Numerical Input and Output
Scheme allows all of the traditional ways of expressing numerical
constants, though only some may be supported by any particular
implementation. These expressions are intended to be purely
notational; any kind of number may be expressed in any form that the
user deems convenient. Of course, expressing 1/7 as a
limited-precision decimal fraction will not exactly express the
number, but this approximate expression may be just what the user
wants to see.
The expressions of numerical constants can be specified using formats.
The system provides a procedure, NUMBER->STRING, which takes a number
and a format and which produces a string which is the printed
expression of the given number in the given format.
(number->string <number> <format>) ==> <string>
This procedure will mostly be used by sophisticated users and in
system programs. In general, a naive user will need to know nothing
about the formats because the system printer will have reasonable
default formats for all types of NUMBERs. The system reader will
construct reasonable default numerical types for numbers expressed in
each of the formats it recognizes. If a user needs control of the
coercion from strings to numbers he will use STRING->NUMBER, which
takes a string, an exactness, and a radix and which produces a number
of the maximally precise applicable type expressed by the given
string.
(string->number <string> E|I B|O|D|X) ==> <number>
!
Formats may have parameters. For example, the "(SCI 5 2)" format
specifies that a number is to be expressed in FORTRAN scientific
format with 5 significant places and two places after the radix point.
The following are all numerical constant expressions. The comment
shows the format that was used to produce the expression:
123 +123 -123 ; (INT) format
12345678901234567890123456789 ; A big one
355/113 -355/113 +355/113 ; (RAT) format
+123.45 -123.45 ; (FIX 2) format
3.14159265358979 ; (FIX 14) format
3.14159265358979 ; (FLO 15) format
123.450 ; (FLO 6) format
-123.45E-1 ; (SCI 5 2) format
123E3 123E-3 -123E-3 ; (SCI 3 0) format
-1+2i ; (RECT (INT) (INT)) format
1.2@1.570796 ; (POLAR (FIX 1) (FLO 7)) format
A numerical constant may be specified with an explicit radix by a
prefix. The prefixes are: #B (binary), #O (octal), #D (decimal), #X
(hex). A format may specify that a number be expressed in a
particular radix. The radix prefix may be suppressed. For example,
one may express a complex number in polar form with the magnitude in
octal and the angle in decimal as follows:
#o1.2@#d1.570796327 ;(POLAR (FLO 2 (RADIX O)) (FLO (RADIX D))) format
#o1.2@1.570796327 ;(POLAR (FLO 2 (RADIX O)) (FLO (RADIX D S)) format
A numerical constant may be specified to be either EXACT or INEXACT by
a prefix. The prefixes are: #I (inexact), #E (exact). An exactness
prefix may appear before or after any radix prefix that is used. A
format may specify that a number be expressed with an explicit
exactness prefix, or it may force the exactness to be suppressed. For
example, the following are ways to output an inexact value for pi:
#I355/113 ; (RAT (EXACTNESS))
355/113 ; (RAT (EXACTNESS S))
#I3.1416 ; (FIX 4 (EXACTNESS))
An attempt to produce more digits than are available in the internal
machine representation of a number will be marked with a "#" filling
the extra digits. This is not a statement that the implementation
knows or keeps track of the significance of a number, just that the
machine will flag attempts to produce 20 digits of a number which has
only 15 digits of machine representation:
3.14158265358979##### ; (FLO 20 (EXACTNESS S))
In systems with both single and double precision FLONUMs one may want
to specify which size we want to use to internally represent a
constant. For example, we may want a constant whidh is pi rounded to
!
the single precision length, or we might want a long number which has
the value 6/10. In either case, we are specifying an explicit way to
represent an INEXACT number. For this purpose, we allow one to
express a number with a prefix which indicates short or long FLONUM
representation:
#S3.14159265358979 ; Round to short -- 3.141593
#L.6 ; Extend to long -- .600000000000000
Details of formats
The format of a number is notated as a list beginning with a
format descriptor, such as SCI. Following the descriptor are
parameters used by that descriptor, such as the number of significant
digits to be used. Parameters which are omitted are defaulted. Next,
one may specify modifiers, such as RADIX or EXACTNESS, which
themselves may be parameterized. The format descriptors are:
(INT)
Express as an integer. The radix point is implicit. If there are
not enough significant places, as in trying to express 6.0238E23
(internally represented as a 7 digit FLONUM) as an integer we would
get "6023800################".
(RAT n)
Express as a rational fraction. n specifies the largest
denominator to be used in constructing a rational approximation to
the number being expressed. If n is omitted it defaults to
infinity.
(FIX n)
Express with a fixed radix point. n specifies the number of
places to right of the radix point. n defaults to the size of a
single-precision FLONUM. If there are not enough significant
places, as in trying to express 6.0238E23 (internally represented
as a 7 digit FLONUM) as a (FIX 2) we would get
"6023800################.##".
(FLO n)
Express with a floating radix point. n specifies the total number
of places to be displayed. n defaults to the size of a single-
precision FLONUM. If the number is out of range, it is converted
to (SCI). (FLO H) allows the system to heuristically express a FLO
for human consumption (as in MacLisp printer).
!
(SCI n m)
Express in exponential notation. n specifies the total number of
places to be displayed. n defaults to the size of a single-
precision FLONUM. m specifies the number of places to the right of
the radix point. m defaults to n-1. (SCI H) does heuristic
expression.
(RECT r i)
Express as a rectangular form complex number. r and i are formats
for the real and imaginary parts respectively. They default to
(HEUR).
(POLAR m a)
Express as a polar form complex number. m and a are formats for
the magnitude and angle respectively. m and a default to (HEUR).
(HEUR)
Express heuristically, as in the MacLisp printer (see Steele),
using the minimum number of digits required to get an expression
which when coerced back to a number produces the original machine
representation. EXACT numbers are expressed as (INT) or (RAT).
INEXACT numbers are expressed as (FLO H) or (SCI H) depending on
their range. Complex numbers are expressed in (RECT). This is the
normal default of the system printer.
The following modifiers may be added to a numerical format
specification:
(EXACTNESS s)
This controls the expression of the exactness label of a number. s
indicates whether the exactness is to be E (expressed) or S
(suppressed). s defaults to E. If no exactness modifier is
specified for a format the exactness is by default not expressed.
(RADIX r s)
This forces a number to be expressed in the radix r. r may be B
(binary), O (octal), D (decimal), or X (hex). s indicates whether
the radix label is to be E (expressed) or S (suppressed). s
defaults to E. If no radix modifier is specified the default is
decimal and the label is suppressed.
-------
∂11-Mar-85 2110 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa I/O proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 11 Mar 85 21:09:47 PST
Received: from csnet-relay by MIT-MC.ARPA; 11 MAR 85 23:49:17 EST
Received: from indiana by csnet-relay.csnet id ac04021; 11 Mar 85 23:37 EST
Date: Mon, 11 Mar 85 23:20:31 est
From: Will Clinger <willc%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA14898; Mon, 11 Mar 85 23:20:31 est
To: scheme@mit-mc.ARPA
Subject: I/O proposal
From Gary Brooks and William Clinger at Indiana U:
This is an interim proposal. It takes an old-fashioned view of
streams, and it does nothing about windows and graphics. Arguments to
functions are delimited by angle brackets (<...>) and optional arguments
are further delmited by curly brackets ({...}).
(eof? <object>) Essential
EOF? takes an object and returns true if the object is an end of
file object. The precise set of end of file objects will vary
among implementations, but in any case no end of file object will
ever be a character or an object that can be read in using READ.
Rationale:
A fixed set of end of file objects seems to be simpler than
allowing each input procedure to take yet another optional
argument specifying what to do on end of file. Allowing for a
set of such objects rather than a single such object allows for
different implementation strategies.
(read {<stream>}) Essential
READ takes an input stream as argument and returns the next
object parsable from the stream, updating the stream to point to
the first character past the end of the written representation of
the object. If an end of file is encountered in the input before
any characters are found that can begin an object, then an end of
file object is returned. If an end of file is encountered after
the beginning of an object's written representation, but the
written representation is incomplete and therefore not parsable,
an error must be signalled. The stream argument to READ may be
omitted, in which case it defaults to (CURRENT-INPUT-STREAM).
Rationale:
READ corresponds to Common Lisp's READ-PRESERVING-WHITESPACE.
This will require something like UNREAD-CHAR or PEEK-CHAR
internally. For simplicity, it is never an error to encounter
end of file when READ is called.
(write <object> {<stream>}) Essential
WRITE takes an object and an output stream and writes a
representation of the object to the stream. Strings that appear
in the written representation are enclosed in double quotes, and
within those strings backslash and double quote characters are
escaped by backslashes. (Implementations that allow
slashification within symbols will probably want WRITE to
slashify funny characters in symbols as well.) WRITE returns an
unspecified value. The stream argument to WRITE may be omitted,
in which case it defaults to (CURRENT-OUTPUT-STREAM).
(display <object> {<stream>}) Essential
DISPLAY takes an object and an output stream and writes a
representation of the object to the stream. Strings that appear
in the written representation are not enclosed in double quotes,
and no characters are escaped within those strings. DISPLAY
returns an unspecified value. The stream argument to DISPLAY may
be omitted, in which case it defaults to (CURRENT-OUTPUT-STREAM).
Rationale:
WRITE is for producing machine-readable output, DISPLAY for
producing human-readable output.
(newline {<stream>}) Essential
NEWLINE takes an output stream and writes a newline to the
stream. NEWLINE returns an unspecified value. The stream
argument to NEWLINE may be omitted, in which case it defaults to
(CURRENT-OUTPUT-STREAM).
Rationale:
NEWLINE abstracts away from the implementation details of
ending a line (or is it starting a new one?).
(listen? {<stream>}) Optional
LISTEN? takes an input stream (an interactive stream in the
useful case) and returns true if a character is ready on that
stream so that a READ-CHAR operation will not hang and returns
false if a READ-CHAR operation will hang. If the stream is at
end of file then the value returned by LISTEN? is unspecified.
Rationale:
LISTEN? is needed for interactive input streams.
(read-char {<stream>}) Essential
READ-CHAR takes an input stream and returns the next character
available from the stream, updating the stream to point to the
following character. If no more characters are available from
the stream, an end of file value is returned. The stream
argument to READ-CHAR may be omitted, in which case it defaults
to (CURRENT-INPUT-STREAM).
(display-char <character> {<stream>}) Essential
DISPLAY-CHAR takes a character and an output stream, and writes
the character itself (not a written representation of the
character) to the stream. DISPLAY-CHAR returns an unspecified
value. The stream argument to DISPLAY-CHAR may be omitted, in
which case it defaults to (CURRENT-OUTPUT-STREAM).
Rationale:
READ-CHAR and DISPLAY-CHAR are for low-level I/O.
(load <filename>) Essential
LOAD takes a string that names an existing file containing Scheme
source code. It reads Scheme expressions from the file and
interprets them sequentially as though they had been typed
interactively. It is not specified whether the results of the
expressions are printed. Neither is it specified whether or not the
LOAD procedure affects the values returned by (CURRENT-INPUT-STREAM)
and (CURRENT-OUTPUT-STREAM) during the loading process. LOAD returns
an unspecified value.
Rationale:
For portability LOAD must operate on source files. Its operation
on other kinds of files necessarily varies among implementations.
(transcript-on <file-name>) Optional
TRANSCRIPT-ON takes a string that names an output file to be
created, and returns an unspecified value. The effect of
TRANSCRIPT-ON is to open the named file for output, and to cause
a transcript of subsequent interaction between the user and the
Scheme system to be written to the file. The transcript is ended
by a call to TRANSCRIPT-OFF. Only one transcript may be in
progress at any time. (Some implementations may relax this
restriction.)
(transcript-off) Optional
TRANSCRIPT-OFF takes no arguments and returns an unspecified
value. It ends any transcript in progress and closes the
transcript file.
Rationale:
TRANSCRIPT-ON and TRANSCRIPT-OFF are redundant in some systems,
but systems that need them should provide them.
(stream? <object>) Essential
STREAM? takes one argument and returns true iff its argument is a
stream.
Rationale:
Perhaps STREAM? should be subdivided into INPUT-STREAM? and
OUTPUT-STREAM?.
(current-input-stream) Essential
CURRENT-INPUT-STREAM takes no arguments and returns the current
default input stream.
(current-output-stream) Essential
CURRENT-OUTPUT-STREAM takes no arguments and returns the current
default output stream.
Rationale:
CURRENT-INPUT-STREAM and CURRENT-OUTPUT-STREAM are procedures
rather than variables to allow for various ways to implement the
default streams. Explicit fetching of the default streams is
convenient for programs that want to change the default stream
using WITH-INPUT-FROM-FILE or WITH-OUTPUT-TO-FILE and still use
the original default stream for some I/O; see below.
(call-with-input-file <string> <procedure>) Essential
CALL-WITH-INPUT-FILE takes a procedure of one argument and a
string naming an existing file and calls the procedure with the
stream obtained by opening the named file for input. If the
file cannot be opened, an error should be signalled. If the
procedure returns, then the stream is closed automatically and
the value yielded by the procedure is returned by
CALL-WITH-INPUT-FILE. If the current continuation ever changes in
such a way as to make it doubtful that the procedure will return,
CALL-WITH-INPUT-FILE may close the input stream. The exact
interaction of escape procedures with CALL-WITH-INPUT-FILE is
unspecified.
(call-with-output-file <file-name> <procedure>) Essential
CALL-WITH-OUTPUT-FILE takes a procedure of one argument and a string
naming a file to be created and calls the procedure with the stream
obtained by opening the named file for output. If the file cannot be
be opened, an error should be signalled. If a file with that name
already exists, the effect is unspecified. If the procedure returns,
then the stream is closed automatically and the value yielded by the
procedure is returned by CALL-WITH-OUTPUT-FILE. If the current
continuation ever changes in such a way as to make it doubtful that
the procedure will return, CALL-WITH-OUTPUT-FILE may close the output
stream. The exact interaction of escape procedures with
CALL-WITH-OUTPUT-FILE is unspecified.
Rationale:
CALL-WITH-INPUT-FILE and CALL-WITH-OUTPUT-FILE are convenient for
programs that need to read input from or send output to several
directions at once. They cannot be synthesized from
WITH-INPUT-FROM-FILE and WITH-OUTPUT-TO-FILE so they are the essential
procedures. Whether or not they close files when there is a throw out
of the procedure is mainly a performance issue, of greatest importance
when there is a small limit on the number of files that can be open at
once. If they close files for a throw, then the vagueness of what it
means for the current continuation to change in such a way as to make
it doubtful that a procedure will return, the possibility of a throw
back in, and the vagueness of what it means to close a file, make it
unwise to specify the exact interaction of the file-closing mechanism
with escape procedures.
It is arguable whether the notion of closing a file should be
reflected in the semantics of Scheme. Operating systems require
that files be closed for the following reasons:
1. To reclaim storage. This should be left to the garbage
collector.
2. To prevent some table in the operating system from
overflowing because there are too many files open at once.
Only implementations that have this problem should have to
worry about it.
3. To facilitate file locking. This seems to be the only
semantic reason for closing a file, and even so there are
implementations for which it isn't meaningful.
Because some systems have to worry about closing files, however,
all portable Scheme code must worry about it. We have tried to
follow MIT's lead in isolating the worry within a few standard
procedures.
(open-input-file <file-name>) Optional
OPEN-INPUT-FILE takes a string naming an existing file and
returns an input stream capable of delivering characters from the
file. If the file cannot be opened, an error should be signalled.
(open-output-file <file-name>) Optional
OPEN-OUTPUT-FILE takes a string naming an output file to be
created and returns an output stream capable of writing
characters to a new file by that name. If the file cannot be
opened, an error should be signalled. If a file with the given
name already exists, the effect is unspecified.
(close-input-stream <stream>) Optional
CLOSE-INPUT-STREAM takes an input stream and returns an
unspecified value. If the stream is connected to a file, the
file is closed and the stream rendered incapable of delivering
characters.
(close-output-stream <stream>) Optional
CLOSE-OUTPUT-STREAM takes an output stream and returns an
unspecified value. If the stream is connected to a file, the
file is closed and the stream rendered incapable of writing
characters to it.
Rationale:
OPEN-INPUT-FILE, OPEN-OUTPUT-FILE, CLOSE-INPUT-STREAM, and
CLOSE-OUTPUT-STREAM are needed to use streams whose lifetimes are
not properly nested, which is to say they are seldom needed.
OPEN-INPUT-FILE and OPEN-OUTPUT-FILE are distinct to avoid the
need for a switch argument; if independent switches were
required, it would be better to use switches rather than have a
product space of procedures. CLOSE-INPUT-STREAM and
CLOSE-OUTPUT-STREAM could probably be combined into CLOSE-STREAM
with no great loss. A different set of procedures will
be needed to create streams from and to strings, and the closing
procedures should still work on them. It seems that closing a
string output stream should yield a string, but it isn't clear
what should be returned when a file output stream is closed.
(with-input-from-file <file-name> <thunk>) Optional
WITH-INPUT-FROM-FILE takes a string and a thunk (a procedure of
no arguments). The string must name an existing file. The file
is opened for input, an input stream connected to it is made the
default value returned by (CURRENT-INPUT-STREAM), and the thunk
is invoked. When the thunk returns, (CURRENT-INPUT-STREAM) is
closed and the previous default value returned by
(CURRENT-INPUT-STREAM) is restored. WITH-INPUT-FROM-FILE returns
the value returned by the thunk. Furthermore WITH-INPUT-FROM-FILE
should attempt to close the input stream and restore the default
input stream whenever the current continuation changes in such a
way as to make it doubtful that the thunk will ever return.
(with-output-to-file <file-name> <thunk>) Optional
WITH-OUTPUT-TO-FILE takes a stfung and a thunk. The string names
an output file to be created. The file is opened for output, an
output stream connected to it is made the default value returned
by (CURRENT-OUTPUT-STREAM), and the thunk is invoked. When the
thunk returns, (CURRENT-OUTPUT-STREAM) is closed and the previous
default value returned by (CURRENT-OUTPUT-STREAM) is restored.
WITH-OUTPUT-FROM-FILE returns the value returned by the thunk.
Furthermore WITH-OUTPUT-FROM-FILE should attempt to close the
output stream and restore the default output stream whenever the
current continuation changes in such a way as to make it doubtful
that the thunk will ever return.
It has been suggested that if evaluation of the thunk is
abandoned and later continued then the file should be re-opened
in exactly the same state that it had been in when it was last
closed, but this may be awkward or inefficient in some
implementations.
Rationale:
WITH-INPUT-FROM-FILE and WITH-OUTPUT-TO-FILE are sufficient for
programs that only use one input or one output at a time. Indeed
by nesting them and by fetching the various nested streams using
CURRENT-INPUT-STREAM and CURRENT-OUTPUT-STREAM, arbitrarily many
input or output files may be used. The automatic closing of the
streams may not be terribly important in some implementations,
but the fact that the old defaults are restored is important
semantically. There are several incompatible ways that they
could interact with escape procedures, however, and at this time
it isn't entirely clear which ways are best. See rationale for
CALL-WITH-OUTPUT-FILE and CALL-WITH-INPUT-FILE.
∂12-Mar-85 0940 @MIT-MC:mw%brandeis.csnet@csnet-relay.arpa Re: Numbers Committee Report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 12 Mar 85 09:40:41 PST
Received: from csnet-relay by MIT-MC.ARPA; 12 MAR 85 12:39:35 EST
Received: from brandeis by csnet-relay.csnet id ac08006; 12 Mar 85 12:36 EST
Received: by brandeis.ARPA (4.12/4.7)
id AA01743; Tue, 12 Mar 85 11:08:41 est
Date: 12 Mar 1985 10:57-EST
From: mw%brandeis.csnet@csnet-relay.arpa
In-Real-Life: Mitchell Wand,faculty
Subject: Re: Numbers Committee Report
To: scheme@mit-mc.ARPA
Message-Id: <479491071/mw@brandeis>
Three comments (of #I10e10):
1. (/ z1 ... zi) ==> ((z1 / z2) ... / zi)
-- since / is not associative, the order of operation should be
specified explicitly. This is probably just an editing issue.
2. Are formats list structures or some other kind of object? That is
do you write
(let ((format (cons 'FLO '(13))))
(number->string z format))
or is FLO some kind of functional object?
3. In paragraph K, are real, integer, etc supposed to be functions or
keywords? That is, can you write
(let ((range real))
((range sqrt) x)) ?
In either case, this proposal ties up those identifiers in a pretty
complicated way. I am not sure how bad this is, but it deserves
thought.
-- Mitch Wand
∂12-Mar-85 0954 @MIT-MC:mw%brandeis.csnet@csnet-relay.arpa Re: I/O proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 12 Mar 85 09:54:14 PST
Received: from csnet-relay by MIT-MC.ARPA; 12 MAR 85 12:52:56 EST
Received: from brandeis by csnet-relay.csnet id ag08006; 12 Mar 85 12:39 EST
Received: by brandeis.ARPA (4.12/4.7)
id AA02554; Tue, 12 Mar 85 12:08:14 est
Date: 12 Mar 1985 11:22-EST
From: mw%brandeis.csnet@csnet-relay.arpa
In-Real-Life: Mitchell Wand,faculty
Subject: Re: I/O proposal
To: scheme@mit-mc.ARPA
Message-Id: <479492551/mw@brandeis>
A few remarks:
1. LOAD does not specify how it interacts with CURRENT-INPUT-STREAM or
CURRENT-OUTPUT-STREAM while loading. What is to be the preferred way
of loading a bootstrap of the following form:
(define! foo ...)
(define! bar (foo (read)))
..complicated data to be processed by foo during load..
It might be argued that this is bad style, but I am not convinced:
such a bootstrap is less dependent on operating system file naming
conventions than one with the data in a separate file.
2. "A different set of procedures will be needed to create streams from
and to strings, and the closing procedures should still work on them.
It seems that closing a string output stream should yield a string, but
it isn't clear what should be returned when a file output stream is
closed."
I don't understand this at all. The phrase "create streams from and to
strings" is rather difficult to parse, which doesn't help.
3. Are with-input-from-file and with-output-from-file the only way to
change the value of (current-input-stream) and (current-output-stream) ?
If so, shouldn't they be essential ?
-- Mitch Wand
∂12-Mar-85 1306 @MIT-MC:GJS@MIT-OZ Re: Numbers Committee Report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 12 Mar 85 13:04:10 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 12 MAR 85 16:03:00 EST
Date: Tue 12 Mar 85 16:02:43-EST
From: Gerald Jay Sussman <GJS%MIT-OZ@MIT-MC.ARPA>
Subject: Re: Numbers Committee Report
To: mw%brandeis.csnet@CSNET-RELAY.ARPA
cc: scheme@mit-mc.ARPA
In-Reply-To: Message from "mw%brandeis.csnet@csnet-relay.arpa" of Tue 12 Mar 85 10:57:00-EST
Three comments (of #I10e10):
***** I certainly hope there are fewer than that!
1. (/ z1 ... zi) ==> ((z1 / z2) ... / zi)
-- since / is not associative, the order of operation should be
specified explicitly. This is probably just an editing issue.
***** I agree and I have already fixed that.
2. Are formats list structures or some other kind of object? That is
do you write
(let ((format (cons 'FLO '(13))))
(number->string z format))
or is FLO some kind of functional object?
***** My initial response is that formats are simple list structures --
there may be some format interpreter, but it should not be part of
Scheme. Presumably this can be later generalized and simplified, if
someone wants to go through the trouble, but I would be happy with
the dumb idea.
3. In paragraph K, are real, integer, etc supposed to be functions or
keywords? That is, can you write
(let ((range real))
((range sqrt) x)) ?
In either case, this proposal ties up those identifiers in a pretty
complicated way. I am not sure how bad this is, but it deserves
thought.
***** The type-restriction operations are intended to be scheme procedures
which take procedures as arguments and which produce procedures as
values. They are bound in the initial environment to the operator
symbols REAL, INTEGER, etc. They may be passed as arguments, etc.
Thus, this does not tie up the identifiers at all, and the example
you give shows that.
-------
∂12-Mar-85 1441 @MIT-MC:CPH@MIT-OZ I/O proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 12 Mar 85 14:41:18 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 12 MAR 85 17:39:56 EST
Date: Tue, 12 Mar 1985 17:25 EST
Message-ID: <CPH.12094520544.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: Will Clinger <willc%indiana.csnet@CSNET-RELAY.ARPA>
Cc: scheme@MIT-MC.ARPA
Subject: I/O proposal
In-reply-to: Msg of 11 Mar 1985 23:20-EST from Will Clinger <willc%indiana.csnet at csnet-relay.arpa>
The I/O proposal seems quite good! In fact it is nearly identical to
the current MIT Scheme I/O system, which makes me happy.
I wonder why you chose the name "DISPLAY-CHAR" rather than
"WRITE-CHAR"? I prefer "WRITE-CHAR" because it has no connotations of
display terminals, or of being viewed by a human; it says, simply,
that the character was written down somewhere.
Also, I think that you should have both "STREAM?" and its components
"INPUT-STREAM?" and "OUTPUT-STREAM?", because it makes more
information available without really constraining the implementation
in any fundamental way. Clearly bidirectional streams can satisfy
both predicates.
Chris Hanson
∂12-Mar-85 1552 @MIT-MC:GJS@MIT-OZ Re: I/O proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 12 Mar 85 15:52:35 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 12 MAR 85 18:51:29 EST
Date: Tue 12 Mar 85 18:51:01-EST
From: Gerald Jay Sussman <GJS%MIT-OZ@MIT-MC.ARPA>
Subject: Re: I/O proposal
To: willc%indiana.csnet@CSNET-RELAY.ARPA
cc: scheme@mit-mc.ARPA
In-Reply-To: Message from "Will Clinger <willc%indiana.csnet@csnet-relay.arpa>" of Tue 12 Mar 85 00:12:50-EST
I think the I/O proposal is very nice. The only objection I have is the
use of the word STREAM for the IO stuff. My problem is that we used that
word all through chapter 3 of our book to mean the functional programming
idea of (potentially) infinite sequence. It will be very painful to change
that. I propose that the word be changed to one of CHANNEL, PIPE, PORT, TUBE,
or any other appropriate euphemism. I believe that my use of the word STREAM
is consistent with that of other authors on functional programming.
-------
∂14-Mar-85 1024 JAR@MIT-MC interaction of LOAD and CURRENT-INPUT-STREAM
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 14 Mar 85 10:24:15 PST
Date: 14 March 1985 13:23-EST
From: Jonathan A Rees <JAR @ MIT-MC>
Subject: interaction of LOAD and CURRENT-INPUT-STREAM
To: mw%brandeis.csnet @ CSNET-RELAY
cc: SCHEME @ MIT-MC
Date: 12 Mar 1985 11:22-EST
From: mw%brandeis.csnet at csnet-relay.arpa
1. LOAD does not specify how it interacts with CURRENT-INPUT-STREAM or
CURRENT-OUTPUT-STREAM while loading. What is to be the preferred way
of loading a bootstrap of the following form:
(define! foo ...)
(define! bar (foo (read)))
..complicated data to be processed by foo during load..
It might be argued that this is bad style, but I am not convinced:
such a bootstrap is less dependent on operating system file naming
conventions than one with the data in a separate file.
I don't see any reason for LOAD and CURRENT-INPUT-STREAM to interact,
and I think it is much better for them not to. If they don't interact
you have a much better invariants on each, e.g.: doing LOAD on a file is
the same as doing LOAD on a file consisting of the string "(begin "
appended to the file appended to the string ")".
What's wrong with writing
(define! foo ...)
(define! bar (foo '
..complicated data to be processed by foo during load..
)) ?
This way you don't need to do explicit I/O at all.
... And incidentally, I don't remember the rationale for having both
DEFINE! and DEFINE. I understand why DEFINE shouldn't have hairy
syntax, but what does DEFINE! give you that the stripped-down DEFINE
doesn't?
Jonathan
∂14-Mar-85 1228 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa Re: I/O proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 14 Mar 85 12:28:17 PST
Received: from csnet-relay by MIT-MC.ARPA; 14 MAR 85 15:27:14 EST
Received: from ti-csl by csnet-relay.csnet id a021223; 14 Mar 85 14:58 EST
Date: 14 Mar 1985 0952-CST
From: David Bartley <Bartley%ti-csl.csnet@csnet-relay.arpa>
Subject: Re: I/O proposal
To: willc%indiana.csnet@csnet-relay.arpa, scheme@mit-mc.ARPA
cc: Bartley%ti-csl.csnet@csnet-relay.arpa
In-Reply-To: Your message of 12-Mar-85 1001-CST
Received: from csl60 by ti-csl; Thu, 14 Mar 85 11:04 CST
Will-- A few questions and remarks about your I/O proposal:
-- What happened to the names PRIN1 and PRINC? Are your WRITE and DISPLAY
meant to be equivalent, respectively, to PRIN1 and PRINC? As I understand
page 382 of the Common LISP (CL) book, your WRITE is not incompatible with
CL's. Likewise, CL doesn't seem to have a DISPLAY. However, I am bothered
by my intuition that DISPLAY should be a terminal-oriented operation.
Bottom line: I vote to go with WRITE and DISPLAY, but the names PRIN1
and PRINC should be reserved as well (as optional aliases). The PRINT
operation should also be optional, with the CL-compatible meaning we agreed
on at the workshop.
-- DISPLAY-CHAR seems to be a redundant, restricted form of DISPLAY. Since
DISPLAY is essential, DISPLAY-CHAR should be dropped.
-- The name LISTEN? also is slightly unintuitive to me; how about INPUT?,
or MORE-INPUT?, or something with "peek" in it.
-- Does READ-CHAR wait for interactive input or return an eof token if
nothing has been buffered up from the keyboard (or comm device, etc)?
-- I oppose the term "stream" and thus the names STREAM?, CURRENT-INPUT-
STREAM, etc., for the reasons Gerry gave. We use "port".
-- With my Pascal (and English) background, I can't help but think of
features named with "with", like WITH-INPUT-FROM-FILE, as syntax, not
procedures. [Did you notice how I began the previous sentence?] I would
prefer a special form: (WITH-INPUT-FROM-FILE <file-name> exp ...). This is
more consistent with CL's macro WITH-INPUT-FROM-STRING. The same goes for
WITH-OUTPUT-FROM-FILE.
-- I don't mind your OPEN- and CLOSE- operations, as long as they remain
optional, but I feel bound to implement OPEN and CLOSE compatibly with CL.
-- I like your approach to eof objects.
-- You have no READ-ATOM. Is there general agreement that READ-ATOM is
unimportant? We have it only by inheritance from Scheme 84.
Regards,
David Bartley
-------
∂15-Mar-85 0801 @MIT-MC:CPH@MIT-OZ I/O proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 15 Mar 85 08:00:52 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 15 MAR 85 10:59:37 EST
Date: Fri, 15 Mar 1985 10:58 EST
Message-ID: <CPH.12095236587.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Cc: Scheme@MIT-MC
Subject: I/O proposal
In-reply-to: Msg of 14 Mar 1985 10:52-EST from David Bartley <Bartley%ti-csl.csnet at csnet-relay.arpa>
Date: Thursday, 14 March 1985 10:52-EST
From: David Bartley <Bartley%ti-csl.csnet at csnet-relay.arpa>
-- DISPLAY-CHAR seems to be a redundant, restricted form of DISPLAY. Since
DISPLAY is essential, DISPLAY-CHAR should be dropped.
I don't agree. I think that it is good to have a balanced pair of
procedures for doing character-level I/O.
-- I oppose the term "stream" and thus the names STREAM?, CURRENT-INPUT-
STREAM, etc., for the reasons Gerry gave. We use "port".
Ditto, except that we use "stream" and will cheerfully change it.
-- With my Pascal (and English) background, I can't help but think of
features named with "with", like WITH-INPUT-FROM-FILE, as syntax, not
procedures. [Did you notice how I began the previous sentence?] I would
prefer a special form: (WITH-INPUT-FROM-FILE <file-name> exp ...). This is
more consistent with CL's macro WITH-INPUT-FROM-STRING. The same goes for
WITH-OUTPUT-FROM-FILE.
I disagree -- proliferation of special forms is a communicable disease.
∂16-Mar-85 1017 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Re: I/O proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 16 Mar 85 10:17:40 PST
Received: from csnet-relay by MIT-MC.ARPA; 16 MAR 85 13:16:38 EST
Received: from unc by csnet-relay.csnet id ak00871; 16 Mar 85 13:14 EST
Received: by unc (4.12/4.7) id AA03236; Sat, 16 Mar 85 07:34:57 est
Date: Sat, 16 Mar 85 07:34:57 est
From: Kent Dybvig <dyb%unc.csnet@csnet-relay.arpa>
Message-Id: <8503161234.AA03236@unc>
To: scheme@mit-mc.ARPA
Subject: Re: I/O proposal
I think the overall proposal is quite nice. I do have a couple
of remarks and minor suggestions, though.
1. I would prefer a settable *eof* variable. It is useful sometimes
to specify the value returned on eof. I also think "eof?" is
unnecessarily complex (giving implementors free reign is not
the most important issue here). Besides, if you ask ten people
what they think the function "eof?" does, chances are all ten
will say, "it takes a file as input and returns true iff the
file is at eof." No big deal here, though.
2. I do not think the programmer should be encouraged to change
the default input/output streams. This leads to confusing or
even dangerous behavior when an error or interrupt occurs.
The exception handler normally wants to operate in the same
environment as the interrupted routine, in order that the
user can query the environment (perform stack walkbacks, check
values of variables, etc.). Imagine if the handler prints
a message and queries the user but receives its input from a
disk file because the default input file has been rebound,
e.g. "Really delete *.*? (y/n): ". For this reason, I think
the names should be "default-input-stream" and
"default-output-stream", rather than "current-...". Of course,
"with-input-from-file" and "with-output-to-file" should not be
supported.
I have had experience with this very issue, and troublesome
problems really do occur. I do not want to write every piece of
code to guard against someone changing the default input/output
files on me. I guess we could provide "console-input-stream" and
"console-output-stream" functions, but this seems to complicate
things unnecessarily.
I think it's a good practice anyway to use explicit stream
arguments.
By the way, why are these functions instead of variables?
Isn't this (only perhaps) helping implementrs at the expense
of added complexity?
3. Why have "call-with-input-file" and "call-with-output-file"
rather than an expression-oriented syntax? I think that the
extra level of nesting will be nasty and people will likely
just define syntactic extensions to get rid of it anyway.
(reference my earlier note) I propose:
(with-input-file (<id> <string>) form ...)
and
(with-output-file (<id> <string>) form ...)
with the same semantics. Each set can easily be defined in
terms of the other, but if one is standard it should be the
simplest one to use.
4. I prefer the name "write-char" to "display-char". I take it
the rationale is that "write-char" might imply that it may
be read back in by the function read as a character. I don't
think this is really going to cause confusion; after all, it
may be read back in by read-char, so read-char/write-char is
parallel to to read/write.
..Kent
∂16-Mar-85 1020 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Re: I/O proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 16 Mar 85 10:20:02 PST
Received: from csnet-relay by MIT-MC.ARPA; 16 MAR 85 13:16:44 EST
Received: from unc by csnet-relay.csnet id al00871; 16 Mar 85 13:15 EST
Received: by unc (4.12/4.7) id AA06384; Sat, 16 Mar 85 11:38:25 est
Date: Sat, 16 Mar 85 11:38:25 est
From: Kent Dybvig <dyb%unc.csnet@csnet-relay.arpa>
Message-Id: <8503161638.AA06384@unc>
To: scheme@mit-mc.ARPA
Subject: Re: I/O proposal
I would also like the name "read-char-ready?" instead of "listen?".
∂17-Mar-85 0839 @MIT-MC:JINX@MIT-OZ I/O proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 17 Mar 85 08:38:49 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 17 MAR 85 11:37:49 EST
Date: 17 Mar 1985 11:37 EST (Sun)
Message-ID: <JINX.12095767900.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Kent Dybvig <dyb%unc.csnet@CSNET-RELAY.ARPA>
Cc: scheme@MIT-MC.ARPA
Subject: I/O proposal
In-reply-to: Msg of 16 Mar 1985 07:34-EST from Kent Dybvig <dyb%unc.csnet at csnet-relay.arpa>
Just a few comments:
1. Having a way to detect the end of file is needed, beyond that,
both alternatives (eof? or *eof*) can be trivially implemented on top
of the other. I don't feel strongly about either, but I tend to agree
with Kent Dybvig since I view *eof* as more flexible. If the other
option (eof?) is chosen, I would much rather have the name be
eof-object? .
2. I disagree that the programmer should not be able to change
the current i/o streams. The debugging problem can be trivially fixed
if the error system/debugger always installs the appropriate stream,
and this can be accomplished easily by appropriate
with-input-from-stream and with-output-from-stream.
Note that allowing the programmer to change them allows for a
cheap implementation of trasncript-on and transcript-off if the stream
objects are appropriately powerful (which they probably want to be).
There is good reason for making them functions rather thatn
variables. If they are variables, the implementation cannot easily
cash the internal components of a stream object in the appropriate
places. For example, for faster default output the implementation can
cash in the printer the procedures for printing characters and strings
to the current output-stream. If the variable is changed, the cash
has to be updated which means either that changes to some variables
are noticed (some variables are special, which I think is a bad idea),
or that the printer must check every time it is invoked. Since
with-output-from..., etc, provide ways of redirecting output, and
furthermore, a procedure set-current-output-stream! can be provided,
there is no functionality lost and the implementation has more freedom.
3. Having functions rather than special forms is in general good,
especially since we have not decided whether special form (and macro)
names are scoped in the same environment or in a different one, and
other such issues.
Note that these functions parallel
call-with-current-continuation on which we agreed at the workshop, and
the reasons are mostly the same.
4. I don't particularly care about the name for
is-character-available? (listen?), but there is an important issue
which I believe has not been raised.
On interactive streams users may have the possibility of
erasing typed characters. What happens if listen? returns true and
then the user erases the character? The program which invoked listen?
will probably attempt to read a character thinking that it will not
hang but it will. We had this bug and went to a fair amount of hair
to get it fixed.
I see two possible solutions to this:
- Listen? locks the character if it returns true. This is
ugly since read-character may not be performed for a while, and may
even be bypassed (error exit, etc.)
- Listen? is polymorphic and returns either '() or a character
object if one is available. This assumes that the set of character
objects is disjoint from the set { '() }. No further call to read is
needed. Listen? would then more appropriately be called
non-blocking-read-char. I advocate for this solution.
5. We have not talked at all about keyboard interrupts. It seems
to me that any reasonable implementation should provide a way for the
user to (at least) abort an infinite loop. It would be nice if we had
a simple standard mechanism for doing this, but implementations would
be free to have more keyborad interrupts (we currently have 5 by
default). I propose that we choose some control character (↑G, for
example) which on all implementations and unless inhibited (an editor
may want to do this) will interrupt Scheme and make it return to the
top-level read-eval-print loop.
∂17-Mar-85 1027 @MIT-MC:CPH@MIT-OZ I/O proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 17 Mar 85 10:26:56 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 17 MAR 85 13:24:58 EST
Date: Sun, 17 Mar 1985 13:24 EST
Message-ID: <CPH.12095787388.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
Cc: Kent Dybvig <dyb%unc.csnet@CSNET-RELAY.ARPA>, scheme@MIT-MC.ARPA
Subject: I/O proposal
In-reply-to: Msg of 17 Mar 1985 11:37-EST from Bill Rozas <JINX>
Date: Sunday, 17 March 1985 11:37-EST
From: Bill Rozas <JINX>
1. Having a way to detect the end of file is needed, beyond that,
both alternatives (eof? or *eof*) can be trivially implemented on top
of the other. I don't feel strongly about either, but I tend to agree
with Kent Dybvig since I view *eof* as more flexible. If the other
option (eof?) is chosen, I would much rather have the name be
eof-object? .
I don't think that *EOF* is a good idea, for the following reason: if
the I/O primitives are expected to return this object, they will have
to return it, and if they are written in assembly or some other
non-Scheme language it would require them to do a variable reference.
Or, at the very least, to have some kind of Scheme wrapper that either
passed them the eof object, or detected that they had returned some
other object and substituted that one.
I vastly prefer the idea of a small fixed set of end of file objects,
and I wish that I had thought up the idea myself. However, I agree
that EOF-OBJECT? is a much better name.
If it is felt that there is a need for something like *EOF*, I would
feel better about having a procedural binder, something like
(WITH-EOF-OBJECT <object> (LAMBDA () ...))
which would give the implementer more freedom.
2. I disagree that the programmer should not be able to change
the current i/o streams. The debugging problem can be trivially fixed
if the error system/debugger always installs the appropriate stream,
and this can be accomplished easily by appropriate
with-input-from-stream and with-output-from-stream.
This has been my experience -- we have had this stuff running for
quite some time without problems.
∂17-Mar-85 2041 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa assertions are better than types
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 17 Mar 85 20:41:33 PST
Received: from csnet-relay by MIT-MC.ARPA; 17 MAR 85 23:40:21 EST
Received: from indiana by csnet-relay.csnet id aa08590; 17 Mar 85 23:36 EST
Date: Sun, 17 Mar 85 17:21:05 est
From: Will Clinger <willc%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA03798; Sun, 17 Mar 85 17:21:05 est
To: scheme@mit-mc.ARPA
Subject: assertions are better than types
Gerry's numbers proposal is the first attempt I've ever seen at
doing numbers right, and I'm very excited about it. I've become
concerned about the effectiveness of the type-restricted
operators, however, and I'd like to offer an alternative
proposal.
First of all, let me state my understanding of Gerry's proposal,
as I edited it for the Revised Revised Report. (I know it isn't
written very well -- my concern was growing as I wrote it.)
----------------------------------------------------------------
(number op) procedure
(complex op) procedure
(real op) procedure
(rational op) procedure
(integer op) procedure
These procedures take a numeric operator op and return a
procedure that acts like op except that it is restricted to
operate on numbers of the specified type and to return numbers
of the specified type. The idea of these procedures is
expressed by
(define make-type-restrictor
(lambda (type?)
(lambda (op)
(lambda args
(if (every type? args)
(let ((ans (apply op args)))
(if (type? ans)
ans
(error "Bad result from type-restricted operator")))
(error "Bad argument to type-restricted operator"))))))
(define number (make-type-restrictor number?))
(define complex (make-type-restrictor complex?))
(define real (make-type-restrictor real?))
(define rational (make-type-restrictor rational?))
(define integer (make-type-restrictor integer?))
where EVERY returns true if its first argument, a predicate, is
true of every element of its second argument, a list.
Some implementations may provide a mechanism whereby the
programmer can request that these type restriction procedures be
interpreted as assertions intended to make the code run faster
rather than as requests for type checks.
((real sqrt) 5) --> 2.236067977
((real sqrt) -1) --> error
((integer sqrt) 10) --> error
The programmer who wrote the last example probably wanted to
compute (TRUNCATE ((REAL SQRT) 10)).
[Gerry's rationale would go here.]
----------------------------------------------------------------
My objections:
1. Speaking for myself, I would not want to clutter my code
with all these type-restricted operators as I write the code,
because it would make the code less readable. (I guess
readability is more important to my debugging processes than are
type checks.) I would be willing to add type assertions when the
time came to make the code run fast. Hence for me at least, the
type restrictions would be more important as advice to the
compiler than as debugging aids.
2. The type restrictors require that all operands and the
result be of the same type. This works reasonably well for
numeric operators but is going to be awkward when the time comes
to generalize it to other operators. How am I going to tell the
compiler that the first argument to vector-ref is a vector of
strings?
3. Statically typed languages are mistaken in associating types
with variables, and Gerry is on the right track to associate
type restrictions with operators, but I think most of us would
agree that the right thing to do is to associate types with
values. That leads to my proposal, which follows:
----------------------------------------------------------------
(assert property? obj) procedure
PROPERTY? must be a total (everywhere defined) unary predicate
with no side effects. Returns obj. It is an error if PROPERTY?
is not true of obj, but implementations are not required to
detect the error.
Rationale: In interpreted code, assertions can be used to check
types, loop invariants, and other assertions. In compiled code,
calls to ASSERT have zero overhead but help the compiler to
produce better code. The ASSERT procedure is a moby
generalization of Common Lisp's special form called THE, and of
MacLisp's FIXNUM-IDENTITY and FLONUM-IDENTITY.
----------------------------------------------------------------
Examples:
Here is Gabriel's tak benchmark with type-restricted operators
as in Gerry's proposal:
(define (tak x y z)
(if (not (<? y x)) ; notice that you can't say (integer <?)
z
(tak (tak ((integer -1+) x) y z)
(tak ((integer -1+) y) z x)
(tak ((integer -1+) z) x y))))
Here it is with assertions:
(define (tak x y z)
(assert integer? x)
(assert integer? y)
(assert integer? z)
(if (not (<? y x))
z
(tak (tak (-1+ x) y z)
(tak (-1+ y) z x)
(tak (-1+ z) x y))))
You could also wrap all the references (or calls) to tak in an
integer declaration, but it's easy to see that that's
unnecessary.
Here is doubly recursive Fibonacci:
; Gerry's proposal
(define (fib n)
(if (<? n 2) ; notice again that (integer <?) won't work
n
((integer +) (fib ((integer -) n 1)) (fib ((integer -) n 2)))))
; With assertions
(define (fib n)
(assert integer? n)
(if (<? n 2)
n
(+ (assert integer? (fib (- n 1)))
(assert integer? (fib (- n 2))))))
; With a good compiler, this would suffice.
(define (fib n)
(assert integer? n)
(if (<? n 2)
n
(+ (fib (- n 1)) (fib (- n 2)))))
Of course, if you really wanted fib to run fast, and you didn't
intend to use it with arguments greater than 40, and excellent
compilers were widespread, then you would probably say something
like
(define fib
(let ((fixnum?
(lambda (x)
(and (integer? x)
(not (negative? x))
(<? x 100000000)))))
(rec fib
(lambda (n)
(assert fixnum? n)
(if (<? n 2)
n
(+ (assert fixnum? (fib (- n 1)))
(assert fixnum? (fib (- n 2)))))))))
∂17-Mar-85 2054 @MIT-MC:CPH@MIT-OZ assertions are better than types
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 17 Mar 85 20:54:04 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 17 MAR 85 23:53:02 EST
Date: Sun, 17 Mar 1985 23:52 EST
Message-ID: <CPH.12095901736.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: Will Clinger <willc%indiana.csnet@CSNET-RELAY.ARPA>
Cc: scheme@MIT-MC.ARPA
Subject: assertions are better than types
In-reply-to: Msg of 17 Mar 1985 17:21-EST from Will Clinger <willc%indiana.csnet at csnet-relay.arpa>
Nice! I like it.
∂17-Mar-85 2248 @MIT-MC:KMP@SCRC-STONY-BROOK assertions are better than types
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 17 Mar 85 22:47:47 PST
Received: from SCRC-STONY-BROOK by MIT-MC via Chaosnet; 18 MAR 85 01:46:45 EST
Received: from SCRC-RIO-DE-JANEIRO by SCRC-STONY-BROOK via CHAOS with CHAOS-MAIL id 198848; Mon 18-Mar-85 01:47:30-EST
Date: Mon, 18 Mar 85 01:45 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: assertions are better than types
To: willc%indiana.csnet@CSNET-RELAY.ARPA, scheme@MIT-MC.ARPA
In-Reply-To: The message of 17 Mar 85 17:21-EST from Will Clinger <willc%indiana.csnet@csnet-relay.arpa>
Message-ID: <850318014558.4.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
I haven't had a chance to go over the recent burst of proposals in
enough depth to comment, but will get to it.
Let me mention, though, while I'm thinking about it, that with regard to:
Date: Sun, 17 Mar 85 17:21:05 est
From: Will Clinger <willc%indiana.csnet@csnet-relay.arpa>
... Here is doubly recursive Fibonacci:
; Gerry's proposal
(define (fib n)
(if (<? n 2) ; notice again that (integer <?) won't work
n
((integer +) (fib ((integer -) n 1)) (fib ((integer -) n 2)))))
; With assertions
(define (fib n)
(assert integer? n)
(if (<? n 2)
n
(+ (assert integer? (fib (- n 1)))
(assert integer? (fib (- n 2))))))
; With a good compiler, this would suffice.
(define (fib n)
(assert integer? n)
(if (<? n 2)
n
(+ (fib (- n 1)) (fib (- n 2)))))
Please be careful when writing your compilers not to copy the Maclisp bug
where:
(DEFUN F (X Y) (DECLARE (FIXNUM X Y)) (PLUS X Y))
turns into a single-instruction addition, ignoring overflow. Gerry's proposal
does not specify much of any way to get code that can do that. It was an
unfortunate mistake since when X and Y are large, the addition can overflow
and bad values can get returned (something GJS's proposal frowns on).
When we thought about this in T a long time ago, we noticed that there are
some kinds of integers which can be said in the abstract to be suitable for
machine-instruction operations. For example, things that count other things
in the address space (eg, array indices) are somehow bounded in a way that
you could usefully take advantage of. It may be useful, therefore, to create
a type called something like INDEX which is like INTEGER but is bounded by
the number of addressable things in the world. Then one can write:
(ASSERT INDEX? (+ (ASSERT INDEX? X) (ASSERT INDEX? Y)))
to get a machine-instruction addition in those cases where it is reliable.
Systems which had addressing schemes that made it impossible to place a bound
on the size of an INDEX could just treat it as synonymous with INTEGER, which
would be invisible to the user except performance-wise.
By the way, changing the subject slightly, but still on the topic of assertions,
my original proposal for T was to have PLUS and + be synonyms, but to have
operators ASSERT and MAP-ASSERT which let one write customizations such as:
(DEFINE-OPEN-CODED (+ . ARGS)
(ASSERT INTEGER? (APPLY PLUS (MAP-ASSERT INTEGER? ARGS))))
so that (+ X Y)
would be like (ASSERT INTEGER? (PLUS (ASSERT INTEGER? X) (ASSERT INTEGER? Y)))
or
(DEFINE-OPEN-CODED (INTEGER OPERATOR)
(LAMBDA ARGS (ASSERT INTEGER? (APPLY OPERATOR (MAP-ASSERT INTEGER? ARGS)))))
so that ((INTEGER +) X Y)
would be like (ASSERT INTEGER? (+ (ASSERT INTEGER? X) (ASSERT INTEGER? Y)))
I think MAP-ASSERT got lost from T somewhere along the way, but perhaps it
would be worth picking back up if people thought this sort of thing was fun.
∂18-Mar-85 1045 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Re: I/O proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 18 Mar 85 10:45:12 PST
Received: from csnet-relay by MIT-MC.ARPA; 18 MAR 85 13:25:10 EST
Received: from unc by csnet-relay.csnet id ae00998; 18 Mar 85 13:22 EST
Received: by unc (4.12/4.7) id AA18455; Sat, 16 Mar 85 22:12:45 est
Date: Sat, 16 Mar 85 22:12:45 est
From: Kent Dybvig <dyb%unc.csnet@csnet-relay.arpa>
Message-Id: <8503170312.AA18455@unc>
To: scheme@mit-mc.ARPA
Subject: Re: I/O proposal
(This note should have come before the others, as it was
referenced in one of them -- sorry.)
> I disagree -- proliferation of special forms is a communicable disease.
Addition of new syntax where new syntax makes sense is never
harmful. It's much more clumsy to use a function when what
really makes sense is a proceedure. Ninety-nine times out
of a hundred people are going to type:
(with-output-to-file "fudmich"
(lambda ()
...))
Adding an extra level of complexity (not to mention an extra
level of nesting).
If we continue to use functions where syntax is appropriate,
pretty soon someone will suggest that the reader syntax
"#'exp" should mean "(lambda () exp)".
If keeping the language small is the goal, proliferation of
functions is more harmful; the ``core'' set must include only
special forms that cannot be implemented using syntactic-
extension, plus all of the functions. I can preprocess a
program on my system to take out the syntax before sending
it to you to run it on your system, but you must have the
functions I call (unless I send them all to you).
Granted, with this particular special form, the standard does
not give us enough information to write it as syntax; this is
a shortcoming in the standard, not in syntactic-extension.
..Kent
∂18-Mar-85 1049 JAR@MIT-MC I/O proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 18 Mar 85 10:48:59 PST
Date: 18 March 1985 13:48-EST
From: Jonathan A Rees <JAR @ MIT-MC>
Subject: I/O proposal
To: dyb%unc.csnet @ CSNET-RELAY
cc: SCHEME @ MIT-MC
In-reply-to: Msg of Sat 16 Mar 85 22:12:45 est from Kent Dybvig <dyb%unc.csnet at csnet-relay.arpa>
Date: Sat, 16 Mar 85 22:12:45 est
From: Kent Dybvig <dyb%unc.csnet at csnet-relay.arpa>
> I disagree -- proliferation of special forms is a communicable disease.
Addition of new syntax where new syntax makes sense is never
harmful. It's much more clumsy to use a function when what
really makes sense is a proceedure. Ninety-nine times out
of a hundred people are going to type:
(with-output-to-file "fudmich"
(lambda ()
...))
Adding an extra level of complexity (not to mention an extra
level of nesting).
I would not argue strongly if you claimed that antispecialformism was a
purely religious position (although I'd wonder, since it's so strongly
held in some camps, such as the ones I belong to). One rational
argument, however, might be not necessarily language simplicity, as you
suggested, but rather, program analyzability. Any program-analyzing
program or human must know about ALL special forms in order to do things
such as free variable analysis and substitution; and there is much one
can say about a program without having ANY knowledge of the values of
free variables. So, generally speaking, special forms add to the
complexity of program analysis, whereas procedures (i.e. bindings) do
not, and therefore special forms are to be avoided.
This argument does not necessarily apply to macros (since macro forms
can be expanded), but since Essential Scheme is militant in not having a
theory of macros, that doesn't help much.
If we continue to use functions where syntax is appropriate,
pretty soon someone will suggest that the reader syntax
"#'exp" should mean "(lambda () exp)".
Actually this is not so absurd. I have from time to time toyed with the
idea of a reader syntax for (lambda () ...) in analogy to that for
(quote ...) for this very reason - the presence of such a thing would
often shoot down the conciseness arguments sometimes put forth in favor
of special forms.
Jonathan
∂18-Mar-85 1123 @MIT-MC:GJS@MIT-OZ Re: I/O proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 18 Mar 85 11:22:38 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 18 MAR 85 14:20:44 EST
Date: Mon 18 Mar 85 14:09:28-EST
From: Gerald Jay Sussman <GJS%MIT-OZ@MIT-MC.ARPA>
Subject: Re: I/O proposal
To: dyb%unc.csnet@CSNET-RELAY.ARPA
cc: scheme@MIT-MC.ARPA
In-Reply-To: Message from "Kent Dybvig <dyb%unc.csnet@csnet-relay.arpa>" of Mon 18 Mar 85 14:02:16-EST
I think that syntax is not the right thing if we can avoid it. For
example, one can pass a procedure WITH-OUTPUT-TO-FILE as an argument
or return it as a value... We cannot do that with a syntactic form.
Thus, unless there are overwhelming reasons for introducing syntax, we
really should not do so.
-------
∂18-Mar-85 1159 @MIT-MC:GJS@MIT-OZ Re: assertions are better than types
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 18 Mar 85 11:59:28 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 18 MAR 85 14:56:49 EST
Date: Mon 18 Mar 85 14:01:07-EST
From: Gerald Jay Sussman <GJS%MIT-OZ@MIT-MC.ARPA>
Subject: Re: assertions are better than types
To: willc%indiana.csnet@CSNET-RELAY.ARPA
cc: scheme@MIT-MC.ARPA
In-Reply-To: Message from "Will Clinger <willc%indiana.csnet@csnet-relay.arpa>" of Sun 17 Mar 85 23:42:56-EST
Hi. Before you jump, I just want to clarify a few points about what I
meant by type-restricted operators -- I know I didn't say this in the
draft I sent you, but I didn't realize the scope of possible
confusion. I rspond pointwise:
Willc: Speaking for myself, I would not want to clutter my code
with all these type-restricted operators as I write the code,
because it would make the code less readable. (I guess
readability is more important to my debugging processes than are
type checks.) I would be willing to add type assertions when the
time came to make the code run fast. Hence for me at least, the
type restrictions would be more important as advice to the
compiler than as debugging aids.
GJS: I agree, usually we would not write the ugly kind of code which
is illustrated below:
(define (tak x y z)
(if (not (<? y x)) ; notice that you can't say (integer <?)
z
(tak (tak ((integer -1+) x) y z)
(tak ((integer -1+) y) z x)
(tak ((integer -1+) z) x y))))
Instead we would write something like this:
(define tak
(let ((-1+ (integer -1+))
(<? (integer <?))) ;Note that we can say this, see below!
(lambda (x y z)
(if (not (<? y x))
z
(tak (tak (-1+ x) y z)
(tak (-1+ y) z x)
(tak (-1+ z) x y))))))
Presumably, with a good compiler it would be just as efficient to
write:
(define (tak x y z)
(let ((-1+ (integer -1+))
(<? (integer <?))) ;Note that we can say this, see below!
(if (not (<? y x))
z
(tak (tak (-1+ x) y z)
(tak (-1+ y) z x)
(tak (-1+ z) x y)))))
Willc: The type restrictors require that all operands and the
result be of the same type. This works reasonably well for
numeric operators but is going to be awkward when the time comes
to generalize it to other operators. How am I going to tell the
compiler that the first argument to vector-ref is a vector of
strings?
Willc: These procedures take a numeric operator op and return a
procedure that acts like op except that it is restricted to
operate on numbers of the specified type and to return numbers
of the specified type.
GJS: The type restrictions are not intended to be simply error-checking
on the type of the inputs and outputs, but rather to be an entry to a
more coherent system built on the numerical tower. The idea is that
for each kind of number there is a set of appropriate kinds of operations
that make sense for it. For example, the INTEGERS are a ring, hence they
do not support arbitrary division. This does not stop us from defining
"/" for the INTEGERS to be anything we like, such as an entry to higher
types on the tower. Additionally, I am not even attempting to clarify
the types for things like strings or vectors of strings, since they do
not have the mathematical structure of numbers... This is trying to be a
coherent theory about numbers, rather than an incoherent theory of
everything.
For example, Hal and I have been hacking a new version of generic
arithmetic based on these principles -- I include a fragment for your
amusement. Basically, there is an operation table, and "restrictions"
like INTEGER are things that transform the generic operator, like +,
into the actual operation from the table.
The following code creates a "rational package" for a
given RING, the new objects have type FIELD.
;;; Rational operations generator
(define (make-rational-operations! ring field)
(let ((+r (ring +)) (-r (ring -)) (*r (ring *)) (negate-r (ring negate))
(=r (ring =)) (gcd (ring gcd)) (quotient (ring quotient))
(sign-r (ring sign)) (one-r (ring 'one)) (zero-r (ring 'zero)))
(define (make-rational n d)
(let ((s (sign-r d)))
(cond ((=r one-r s)
(cons '*numeric-type*
(cons field (cons n d))))
((=r zero-r s)
(error "Bad rational construction" field (list n d)))
(else
(cons '*numeric-type*
(cons field
(cons (quotient n s)
(quotient d s))))))))
(define numer caddr)
(define denom cdddr)
(define (+←rational x y)
(let ((d1 (gcd (denom x) (denom y))))
(if (=r one-r d1) ;GIGO
(make-rational (+r (*r (numer x) (denom y))
(*r (denom x) (numer y)))
(*r (denom x) (denom y)))
(let ((dx/d1 (quotient (denom x) d1)))
(let ((tem (+r (*r (quotient (denom y) d1) (numer x))
(*r dx/d1 (numer y)))))
(let ((d2 (gcd tem d1)))
(make-rational (quotient tem d2)
(*r dx/d1
(quotient (denom y) d2)))))))))
(define (-←rational x y)
(+←rational x (make-rational (negate-r (numer y)) (denom y))))
(define (*←rational x y)
(let ((d1 (gcd (numer x) (denom y)))
(d2 (gcd (numer y) (denom x))))
(make-rational (*r (quotient (numer x) d1)
(quotient (numer y) d2))
(*r (quotient (denom x) d2)
(quotient (denom y) d1)))))
(define (/←rational x y)
(*←rational x (make-rational (denom y) (numer y))))
(define (=←rational x y)
(and (=r (numer x) (numer y)) (=r (denom x) (denom y))))
(define (negate-rational x)
(make-rational (negate-r (numer x)) (denom x)))
(define (recip-rational x)
(make-rational (denom x) (numer x)))
(define (raise i)
(make-rational i one-r))
(put-coercion! raise ring field)
(put-op! (raise zero-r) 'zero field)
(put-op! (raise one-r) 'one field)
(put-op! +←rational + field)
(put-op! -←rational - field)
(put-op! *←rational * field)
(put-op! /←rational / field)
(put-op! =←rational = field)
(put-op! negate-rational negate field)
(put-op! recip-rational recip field)
(put-op! (lambda (x) (sign-r (numer x))) sign field)
(put-op! numer numerator field)
(put-op! denom denominator field)
))
;;;Now we can use this to define the rationals over integers
(define (rational op) (get-op op rational))
(define (rational? x)
(or (integer? x)
(eq? (numeric-type x) rational)))
(make-rational-operations! integer rational 'rational)
;;;For these particular rationals, we may also want some additional
;;;operations that are not sensible for arbitrary rationals, e.g.,
;;;based upon polynomial rings. For example:
(define (raise-rational-unary-operation op)
(lambda (x) (op (rational->real x))))
(put-op! (raise-rational-unary-operation sqrt) sqrt rational)
(put-op! (raise-rational-unary-operation sin) sin rational)
(put-op! (raise-rational-unary-operation cos) cos rational)
(put-op! (raise-rational-unary-operation tan) tan rational)
(put-op! (raise-rational-unary-operation real-part) real-part rational)
(put-op! (raise-rational-unary-operation imag-part) imag-part rational)
(put-op! (raise-rational-unary-operation magnitude) magnitude rational)
(put-op! (raise-rational-unary-operation angle) angle rational)
-------
∂18-Mar-85 1210 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa Arithmetic overflow
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 18 Mar 85 12:09:58 PST
Received: from csnet-relay by MIT-MC.ARPA; 18 MAR 85 15:08:58 EST
Received: from indiana by csnet-relay.csnet id a001575; 18 Mar 85 14:38 EST
Date: Mon, 18 Mar 85 10:48:24 est
From: Will Clinger <willc%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA03030; Mon, 18 Mar 85 10:48:24 est
To: scheme@mit-mc.ARPA
Subject: Arithmetic overflow
Kent Pitman points out:
>Please be careful when writing your compilers not to copy the Maclisp bug
>where:
>
>(DEFUN F (X Y) (DECLARE (FIXNUM X Y)) (PLUS X Y))
>
>turns into a single-instruction addition, ignoring overflow. Gerry's proposal
>does not specify much of any way to get code that can do that. It was an
>unfortunate mistake since when X and Y are large, the addition can overflow
>and bad values can get returned (something GJS's proposal frowns on).
I agree whole-heartedly. Like Gerry's proposal, the ASSERT procedure does
not give the programmer the ability to specify that overflow is to be ignored,
though it can be used to assert that a result is within a certain range.
My last fibonacci example was perhaps too subtle. In computing (fib 40), the
arguments to + are always less than 100000000 (the constant appearing in the
fixnum? procedure), but the result is greater than 100000000. A compiler that
assumes that the result of an addition is never greater than the operands is
simply buggy.
Peace, Will Clinger
∂18-Mar-85 1545 @MIT-MC:linus!ramsdell@mitre-bedford Pointer-less stack allocated arrays.
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 18 Mar 85 15:39:44 PST
Received: from mitre-bedford by MIT-MC.ARPA; 18 MAR 85 18:38:27 EST
Date: 18 Mar 1985 18:36:50-EST
From: linus!ramsdell@Mitre-Bedford
Received: by linus.UUCP (4.12/4.7)
id AA07064; Mon, 18 Mar 85 15:17:32 est
Date: Mon, 18 Mar 85 15:17:32 est
From: linus!ramsdell (John D. Ramsdell)
Message-Id: <8503182017.AA07064@linus.UUCP>
To: bccvax!scheme@mit-mc.arpa
Subject: Pointer-less stack allocated arrays.
I recently visited Harvard and had an interesting
conversation with Stavros Macrakis. He is an
Ada proponent with considerable experience with
Lisp, in particular, MacLisp. He was very active
in the Macsyma project and gained much knowledge
about MacLisp's implementation.
I brought up the subject of extensible languages
in reference to Richard Schooler's masters thesis
called "Partial Evaluation as a means of Language
Extensibility", MIT/LCS/TR-324, August 1984. The
thesis suggests that Scheme makes a good intermediate
language; very suitable for partial evaluation.
Stavros immediately rejected the notion that Scheme
makes a good intermediate language because its model
of data is too general. For example, consider the
task of taking the dot product of two vectors represented
by two arrays of floating point numbers. Since arrays can
be returned from the function in which they are created,
they must be allocated from the heap. Since garbage collection
can change the origin of the array, all references to elements
in the array must be accompanied with a reference to the array
header. Thus the compiled code for Scheme can never be as
good as that produced by an Ada compiler said Starvos.
Many years ago, I asked Jonathan Rees if the T compiler could
place arrays on the stack when appropriate and eliminate the
unneccessary indirection in numerical arrays by replacing
pointers to floating point numbers with the actual numbers
as the array elements. He claimed compiler declarations
would make this possible, but had many other more pressing issue
to worry about in regards to the T compiler. I am wondering
if there is interest in using ASSERT to allow the elimination of
many pointers in some programs.
John
∂18-Mar-85 2056 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa Re: I/O proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 18 Mar 85 20:55:51 PST
Received: from csnet-relay by MIT-MC.ARPA; 18 MAR 85 23:54:51 EST
Received: from indiana by csnet-relay.csnet id ab04361; 18 Mar 85 23:38 EST
Date: Mon, 18 Mar 85 16:46:58 est
From: Will Clinger <willc%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA08003; Mon, 18 Mar 85 16:46:58 est
To: scheme@mit-mc.ARPA
Subject: Re: I/O proposal
We thank everyone for their comments on the I/O proposal. Here
are our responses.
>Also, I think that you should have both "STREAM?" and its components
>"INPUT-STREAM?" and "OUTPUT-STREAM?", because it makes more
>information available without really constraining the implementation
>in any fundamental way. Clearly bidirectional streams can satisfy
>both predicates.
Agreed. Any dissent?
----------------------------------------------------------------
>The only objection I have is the
>use of the word STREAM for the IO stuff. My problem is that we used that
>word all through chapter 3 of our book to mean the functional programming
>idea of (potentially) infinite sequence. It will be very painful to change
>that. I propose that the word be changed to one of CHANNEL, PIPE, PORT, TUBE,
>or any other appropriate euphemism. I believe that my use of the word STREAM
>is consistent with that of other authors on functional programming.
>-- I oppose the term "stream" and thus the names STREAM?, CURRENT-INPUT-
>STREAM, etc., for the reasons Gerry gave. We use "port".
Good point, so the names will change as follows:
old name new name
stream? input-port?
output-port?
current-input-stream current-input-port
current-output-stream current-output-port
close-input-stream close-input-port
close-output-stream close-output-port
----------------------------------------------------------------
>-- What happened to the names PRIN1 and PRINC? Are your WRITE and DISPLAY
>meant to be equivalent, respectively, to PRIN1 and PRINC? As I understand
>page 382 of the Common LISP (CL) book, your WRITE is not incompatible with
>CL's. Likewise, CL doesn't seem to have a DISPLAY. However, I am bothered
>by my intuition that DISPLAY should be a terminal-oriented operation.
>
> Bottom line: I vote to go with WRITE and DISPLAY, but the names PRIN1
>and PRINC should be reserved as well (as optional aliases). The PRINT
>operation should also be optional, with the CL-compatible meaning we agreed
>on at the workshop.
Yes, WRITE and DISPLAY correspond to Common Lisp's PRIN1 and
PRINC. For that matter they correspond to T's PRINT and DISPLAY,
and to Scheme-84's DISPLAY and PRINT. Common Lisp's WRITE takes
a stream as a keyword argument whereas Scheme's WRITE takes a
port as an optional argument. If that incompatibility doesn't
bother you then it certainly doesn't bother us.
PRINC and PRINT are used in the Abelson and Sussman book, but we
don't think they deserve or need formal status.
----------------------------------------------------------------
>2. "A different set of procedures will be needed to create streams from
>and to strings, and the closing procedures should still work on them.
>It seems that closing a string output stream should yield a string, but
>it isn't clear what should be returned when a file output stream is
>closed."
>
>I don't understand this at all. The phrase "create streams from and to
>strings" is rather difficult to parse, which doesn't help.
Scheme doesn't have anything comparable to Common Lisp's
READ-FROM-STRING, WRITE-TO-STRING, WITH-INPUT-FROM-STRING, and
WITH-OUTPUT-TO-STRING. When we get around to adding those
capabilities, we will want to package the strings up to look like
ordinary I/O ports that can be passed as the optional argument to
READ and WRITE. It appears that the designers of Common Lisp
didn't quite figure out how they wanted to do it either.
----------------------------------------------------------------
>3. Are with-input-from-file and with-output-from-file the only way to
>change the value of (current-input-stream) and (current-output-stream) ?
>If so, shouldn't they be essential ?
We agree that this is somewhat inconsistent, but there are
difficulties involved with specifying the correct semantics for
WITH-INPUT-FROM-FILE and WITH-OUTPUT-TO-FILE, as well as difficulties
involved with implementing them correctly, so for the time being...
WITH-INPUT-FROM-FILE and WITH-OUTPUT-TO-FILE are the only ways
defined in the proposal to change the default input or output
ports. Implementations may feel that the default ports should
always be the keyboard and screen, or they may prefer alternative
ways to change the default ports. The main reason for making
WITH-INPUT-FROM-FILE and WITH-OUTPUT-TO-FILE optional rather than
essential, however, is that we are not certain of the best way
for them to interact with escape procedures, and it seems a good
idea to keep uncertainties like that out of the essential
language until we understand them better.
----------------------------------------------------------------
>-- DISPLAY-CHAR seems to be a redundant, restricted form of DISPLAY. Since
>DISPLAY is essential, DISPLAY-CHAR should be dropped.
At the workshop it was emphasized that characters may overlap
with numbers, strings, or what have you. If characters are just
numbers, then (DISPLAY #\SPACE) will print something like "32"
whereas (WRITE-CHAR #\SPACE) will print " " (without the double
quotes, of course).
>I wonder why you chose the name "DISPLAY-CHAR" rather than
>"WRITE-CHAR"? I prefer "WRITE-CHAR" because it has no connotations of
>display terminals, or of being viewed by a human; it says, simply,
>that the character was written down somewhere.
WRITE-CHAR it is.
----------------------------------------------------------------
>I don't see any reason for LOAD and CURRENT-INPUT-STREAM to interact,
>and I think it is much better for them not to. If they don't interact
>you have a much better invariants on each, e.g.: doing LOAD on a file is
>the same as doing LOAD on a file consisting of the string "(begin "
>appended to the file appended to the string ")".
We agree entirely, and are flushing the sentence in question.
----------------------------------------------------------------
>-- The name LISTEN? also is slightly unintuitive to me; how about INPUT?,
>or MORE-INPUT?, or something with "peek" in it.
LISTEN? is named after the LISTEN predicate in Common Lisp.
"Peek" calls to mind MacLisp's TYIPEEK, which is unrelated.
We're willing to change the name, and the following are the leading
candidates:
CHAR-READY?
INPUT-READY?
Please send your votes to brooks@indiana before 25 March.
----------------------------------------------------------------
>-- Does READ-CHAR wait for interactive input or return an eof token if
>nothing has been buffered up from the keyboard (or comm device, etc)?
It waits.
----------------------------------------------------------------
>-- With my Pascal (and English) background, I can't help but think of
>features named with "with", like WITH-INPUT-FROM-FILE, as syntax, not
>procedures. [Did you notice how I began the previous sentence?] I would
>prefer a special form: (WITH-INPUT-FROM-FILE <file-name> exp ...). This is
>more consistent with CL's macro WITH-INPUT-FROM-STRING. The same goes for
>WITH-OUTPUT-FROM-FILE.
We prefer procedures to special forms, and we followed MIT's
names here. It is hard to come up with good names for these
procedures.
Thanks again to all who are commenting on the proposals.
Gary Brooks and Will Clinger
∂19-Mar-85 0456 @MIT-MC:forwarder@CSNET-SH.ARPA Message a011267 -- long message to scheme@mit-mc
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 19 Mar 85 04:56:45 PST
Received: from CSNET-SH by MIT-MC.ARPA; 19 MAR 85 07:55:45 EST
To: scheme@MIT-MC.ARPA
cc: willc%indiana.csnet@CSNET-SH.ARPA
Subject: Message a011267 -- long message to scheme@mit-mc
Reply-to: cic@CSNET-SH.ARPA
Date: 19 Mar 85 07:45:58 EST (Tue)
From: "Charlotte D. Mooers" <postmaster@CSNET-SH.ARPA>
This message was rejected by mit-mc for the following reason:
'Message is too large to mail; use FTP.'
Since FTP (file transfer protocol) is not possible between indiana
and mit-mc, I have split up the message into three sections of
1000, 1000 and 695 lines each, which I will send separately.
In the future, please agree on a limit to the length of file that
you will transmit by mail to mit-mc.
---Charlotte Mooers
CSNET Staff
∂19-Mar-85 0459 @MIT-MC:forwarder@CSNET-SH.ARPA Message a011267 LONG message - part 1
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 19 Mar 85 04:58:56 PST
Received: from CSNET-SH by MIT-MC.ARPA; 19 MAR 85 07:56:10 EST
To: scheme@MIT-MC.ARPA
Subject: Message a011267 LONG message - part 1
Reply-to: cic@CSNET-SH.ARPA
Date: 19 Mar 85 07:48:45 EST (Tue)
From: "Charlotte D. Mooers" <postmaster@CSNET-SH.ARPA>
Received: from csnet-relay.arpa by CSNET-SH.ARPA id a028166; 18 Mar 85 13:26 EST
Date: Mon, 18 Mar 85 10:55:42 EST
From: CSNET-RELAY Memo Service (MMDF) <mmdf@CSNET-RELAY.ARPA>
Subject: Failed mail (msg.a011267)
Sender: mmdf@CSNET-RELAY.ARPA
To: Postmaster@CSNET-RELAY.ARPA
Your message could not be delivered to
'scheme@mit-mc.ARPA (host: mit-mc.arpa) (queue: smtp)' for the following
reason: ' Message is too large to mail; use FTP.'
Your message follows:
Received: from indiana by csnet-relay.csnet id a011267; 18 Mar 85 9:36 EST
Date: Mon, 18 Mar 85 01:24:29 est
From: willc@Indiana (Will Clinger)
Received: by iuvax.UUCP; id AA06606; Mon, 18 Mar 85 01:24:29 est
To: scheme@mit-mc
Subject: DRAFT of Revised Revised Report (LONG message)
Here is the DRAFT of the final report on the Brandeis workshop.
It is missing all its appendices, and a couple of sections that
deal with the lexical syntax of numbers need more work. Please
read it and tell me what you think. We'd like to have your
comments by 1 April so we can send it to press.
The font information has been stripped for posting to
scheme@mit-mc. Some ambiguities probably result, but please don't
get upset about them.
If you have anything more to say about Chris Hanson's work on
strings, please say it soon. We'd like to include Chris's work
in this report.
-- Will Clinger
willc@indiana
Table of Contents
Part I: Introduction to Scheme
I.0 Brief history of Scheme
I.1 Syntax of Scheme
I.2 Semantics of Scheme
Part II: A catalog of Scheme
II.0 Notational conventions
II.1 Special forms
II.2 Booleans
II.3 Equivalence predicates
II.4 Pairs and lists
II.5 Symbols
II.6 Numbers (part 1)
II.7 Numbers (part 2)
II.8 Strings
II.9 Vectors
II.10 The object table
II.11 Procedures
II.12 Ports
II.13 Input
II.14 Output
References
Index (not yet ready)
!Acknowledgements
This report is primarily the work of a group of people who met
at Brandeis University for two days in October 1984. The
participants at that workshop were Hal Abelson (MIT), Norman
Adams (Yale), David Bartley (Texas Instruments), Gary Brooks,
(Texas Instruments, Indiana University), William Clinger
(Indiana University), Dan Friedman (Indiana University), Robert
Halstead (MIT), Chris Hanson (MIT), Chris Haynes (Indiana
University), Eugene Kohlbecker (Indiana University), Don Oxley
(Texas Instruments), Jonathan Rees (MIT), Bill Rozas (MIT),
Gerald Sussman (MIT), and Mitchell Wand (Indiana University,
Brandeis). Kent Pitman (MIT) made valuable contributions to the
agenda for the workshop but was unable to attend the sessions.
We would like also to thank the following people for their
comments and criticisms in the months following the workshop:
Kent Dybvig, Andy Freeman, Yekta Gursel, Paul Hudak, Chris
Lindblad, Guy Steele Jr.
We thank Dan Friedman and Chris Haynes for permission to use
text from the Scheme 311 Version 4 reference manual. We
acknowledge the influence of manuals for MIT Scheme, T, Scheme
84, and Common Lisp.
!Part I: Introduction to Scheme
I.0 Brief history of Scheme
Scheme is a programming language invented by Guy Lewis Steele Jr
and Gerald Jay Sussman. It is a statically scoped dialect of
Lisp with an exceptionally clear and simple semantics.
The first description of Scheme was written in 1975 [\ref]. A
Revised Report [\ref] appeared in 1978, which described the
evolution of the language as its MIT implementation was upgraded
to support an innovative compiler [\ref]. Three distinct
projects began in 1981 and 1982 to use variants of Scheme for
courses at MIT, Yale, and Indiana University [\ref, ref, ref].
An excellent introductory computer science textbook using Scheme
was published in 1984 [\ref].
As might be expected of a language used primarily for education
and research, Scheme has always evolved rapidly. This was no
problem when Scheme was used only within MIT, but as Scheme
became more widespread local subdialects began to diverge until
students and researchers occasionally found it difficult to
understand code written at other sites. Fifteen representatives
of the major implementations of Scheme therefore met in October
1984 to work toward a better and more widely accepted standard
for Scheme. This paper reports their unanimous recommendations
augmented by committee work in the areas of input/output and
arithmetic.
Scheme shares with Common Lisp [\ref] the goal of a core
language common to several implementations. Scheme differs from
Common Lisp in that the purpose of the common language has as
much to do with porting ideas as with porting code. It is
appropriate therefore that Scheme is much smaller, is less
pervasively specified, and will evolve faster than Common Lisp.
!I.1 Syntax
Formal definitions of the lexical and context-free syntaxes of
Scheme will be added as appendices.
Identifiers
Most identifiers allowed by other programming languages are also
acceptable to Scheme. The precise rules for forming identifiers
vary among implementations of Scheme, but in all implementations
a sequence of characters that contains no special characters and
begins with a character that cannot begin a number is an
identifier. There may be other identifiers as well, and in
particular the following are identifiers:
+ - 1+ -1+
It is guaranteed that the following characters cannot begin a
number, so identifiers other than the four listed above should
begin with one of:
a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
! $ % & * / : < = > ? ~
Subsequent characters of the identifier should be drawn from:
a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9
! $ % & * / : < = > ? ↑ ← . ~
The case in which the letters of an identifier are typed is
immaterial. For example, Foo is the same identifier as FOO.
The following characters are special, and should never be used
in an identifier:
) ( ] [ } { " ; blank
Scheme deliberately does not specify whether the following
characters can be used in identifiers:
# ' ` , @ \ |
Rationale: Some implementations might want to use backwhack ( \)
and vertical bar ( | ) as in Common Lisp. As for the others
there are two schools of thought. One school argues that
disallowing special characters in identifiers allows the
computer to catch more typing errors. The other school agrees
only for special characters that come in pairs, because errors
that involve only the unpaired special characters are easy to
see.
Numbers
For a description of the notations used for numbers, see section
II.7. A concise summary of the notations used to write numbers
will be added to this section, and a formal description will be
part of the appendix on lexical syntax.
Comments
A semicolon indicates the start of a comment. The comment
continues to the end of the line on which the semicolon appears.
Comments are invisible to Scheme, but the end of the line is
visible as whitespace. This prevents a comment from appearing
in the middle of an identifier or number. Comments may appear
inside a string that extends over more than one line, but it is
probably a bad idea to write such strings because their contents
are implementation-dependent.
Other notations
Left and right parentheses are used for grouping and to notate
lists as described in section II.4. Left and right square
brackets and curly braces are not used in Scheme right now but
are reserved for unspecified future uses.
The quote (') and backquote (`) characters are used to indicate
constant or almost-constant data as described in section II.1.
The comma is used together with the backquote, and the atsign
(@) is used together with the comma.
The doublequote character is used to notate strings as described
in section II.8.
The sharp sign (octathorp) is used for a variety of purposes
depending on the character that follows it. A sharp sign
followed by a left parenthesis signals the beginning of a
vector, as described in section II.9. A sharp sign followed by
an exclamation point is used to notate one of the special values
#!true, #!false, and #!null. A sharp sign followed by a
backslash is used to notate characters as described in section
II.8. A sharp sign followed by any of a number of letters is
used to notate numbers as described in section II.7.
Context free grammar for Scheme
The following grammar is ambiguous because a <special form>
looks like a <procedure call>. Some implementations resolve the
ambiguity by reserving the identifiers that serve as keywords of
special forms, while other implementations allow the keyword
meaning of an identifier to be shadowed by lexical bindings.
<expression> ::= <constant>
| <identifier>
| <special form>
| <procedure call>
<constant> ::= <numeral> | #!true | #!false | #!null
| (quote <datum>) | '<datum>
<special form> ::= (<keyword> ...)
<procedure call> ::= (<expression> <arguments>)
<arguments> ::= <empty> | <expression> <arguments>
<datum> stands for any written representation of a Scheme
object, as described in the sections that follow. <identifier>
and <numeral> have already been described informally. <special
form> stands for one of the special forms whose syntax is
described in section II.1. For uniformity the other kinds of
expressions are also described in that section as though they
were special forms.
!I.2 Semantics
The formal semantics of Scheme will be the subject of an
appendix to be added. The detailed informal semantics of Scheme
is the subject of Part II. This section gives a quick review of
Scheme's major characteristics.
Scheme is a statically scoped programming language, meaning that
each use of an identifier is associated with a lexically
apparent binding of that identifier. In this respect Scheme is
like Algol 60, Pascal, and C but unlike dynamically scoped
languages such as APL and traditional Lisp.
Scheme has latent as opposed to manifest types, which means that
types are associated with values (also called objects) rather
than with variables. (Some authors refer to languages with
latent types as weakly typed or dynamically typed languages.)
Other languages with latent types are APL, Snobol, and other
dialects of Lisp. Languages with manifest types (sometimes
referred to as strongly typed or statically typed languages)
include Algol 60, Pascal, and C.
All objects created in the course of a Scheme computation,
including all procedures and variables, have unlimited extent.
This means in effect that no Scheme object is ever destroyed.
The reason that implementations of Scheme do not (usually!) run
out of storage is that they are permitted to reclaim the storage
occupied by an object if they can prove mathematically that the
object cannot possibly matter to any future computation. Scheme
is a practical programming language only because there exist
fairly efficient "garbage collection" algorithms for performing
these proofs. Other languages in which most objects have
unlimited extent include APL and Common Lisp.
Scheme procedures are objects in their own right. Procedures
can be created dynamically, stored in data structures, returned
as results of procedures, and so on. Other languages with these
properties include Common Lisp, ML, and KRC.
Arguments to Scheme procedures are always passed by value, which
means that the actual argument expressions are evaluated before
the procedure actually gains control, whether the procedure
needs the result of the evaluation or not. ML, C, and APL are
three good examples of other languages that always pass
arguments by value. KRC is a good example of a language that
passes arguments by name, so that an argument expression is
evaluated only if its value is needed by the procedure.
!Part II: A catalog of Scheme
II.0 Notational conventions
This part of the report is a catalog of the special forms and
procedures that make up Scheme. The special forms are described
in section II.1, and the procedures are described in the
following sections. Each section is organized into entries,
with one entry (usually) for each special form or procedure.
Each entry begins with a header line that includes the name of
the special form or procedure in bold face type within a
template for the special form or a call to the procedure. The
names of the arguments to a procedure are italicized, as are the
syntactic components of a special form. A notation such as
expr ...
indicates zero or more occurrences of expr, and so
expr1 expr2 ...
indicates at least one expr.
At the right of the header line one of the following categories
will appear:
special form
constant
variable
procedure
essential special form
essential constant
essential variable
essential procedure
A special form is a syntactic class of expressions, usually
identified by a keyword. A constant is something that is
lexically recognizable as a constant. A variable is an
identifier that is bound to a location in which values (also
called objects) can be stored. Those variables that initially
hold procedure values are identified as procedures.
Implementations are free to omit features of Scheme or to add
extensions, provided the extensions are not in conflict with the
language reported here. It is guaranteed, however, that every
implementation of Scheme will support the essential special
forms, constants, variables, and procedures.
Any Scheme value can be used as a boolean expression for the
purposes of a conditional test. As explained in section II.2,
most values count as true, but a few -- notably #!false -- count
as false. This manual uses the word "true" to refer to any
Scheme value that counts as true in a conditional expression,
and the word "false" to refer to any Scheme value that counts as
false.
!II.1. Special forms
Identifiers have two uses within Scheme programs. When an
identifier appears within a quoted constant (see quote), it is
being used as data as described in the section on symbols.
Otherwise it is being used as a name. There are two kinds of
things that an identifier can name in Scheme: special forms and
variables. A special form is a syntactic class of expressions,
and an identifier that names a special form is called the
keyword of that special form. A variable, on the other hand, is
a location where a value can be stored. An identifier that
names a variable is said to be bound to that location. The set
of all such bindings in effect at some point in a program is
known as the environment in effect at that point.
Certain special forms are used to allocate storage for new
variables and to bind identifiers to those new variables. The
most fundamental of these binding constructs is the lambda
special form, because all other binding constructs can be
explained in terms of lambda expressions. The other binding
constructs are the let, let*, letrec, internal definition (see
define), rec, define!, defrec!, and do special forms.
Like Algol or Pascal, and unlike most other dialects of Lisp
except for Common Lisp, Scheme is a statically scoped language
with block structure. To each place where an identifier is
bound in a program there corresponds a region of the program
within which the binding is effective. The region varies
according to the binding construct that establishes the binding;
if the binding is established by a lambda expression, for
example, then the region is the entire lambda expression. Every
use of an identifier in a variable reference or assignment
refers to the binding of the identifier that set up the
innermost of the regions containing the use. If there is no
binding of the identifier whose region contains the use, then
the use refers to the binding for the identifier that was in
effect when Scheme started up, if any; if there is no binding
for the identifier, it is said to be unbound.
variable essential special form
An expression consisting of an identifier that is not the
keyword of a special form is a variable reference. The value
obtained for the variable reference is the value stored in the
location to which variable is bound. An error is signalled if
variable is unbound.
(procedure arg1 ...) essential special form
A list of expressions whose first element is not the keyword of
a special form indicates a procedure call. The procedure and
argument expressions are evaluated and the procedure is passed
the values of the argument expressions. In constrast to other
dialects of Lisp the order of evaluation is not specified, and
the procedure expression and the argument expressions are always
evaluated in exactly the same way.
(+ 3 4) --> 7
((if #!false + *) 3 4) --> 12
(quote constant) essential special form
'constant essential special form
Evaluates to constant. This notation is used to include literal
constants in Scheme code.
(quote a) --> a
(quote #(a b c)) --> #(a b c)
(quote (+ 1 2)) --> (+ 1 2)
(quote constant) may be abbreviated as 'constant. The two
notations are equivalent in all respects.
'a --> a
'#(a b c) --> #(a b c)
'(+ 1 2) --> (+ 1 2)
'(quote a) --> (quote a)
''a --> (quote a)
Numbers, strings, and the constants #!true, #!false, and #!null
need not be quoted.
'"abc" --> "abc"
"abc" --> "abc"
'145932 --> 145932
145932 --> 145932
'#!true --> #!true
#!true --> #!true
(lambda (var1 ...) expr) essential special form
Each var must be an identifier. The lambda expression evaluates
to a procedure with formal argument list (var1 ...) and
procedure body expr. The environment in effect when the lambda
expression was evaluated is remembered as part of the procedure.
When the procedure is later called with some actual arguments,
the environment in which the lambda expression was evaluated
will be extended by binding the identifiers in the formal
argument list to fresh locations, the corresponding actual
argument values will be stored in those locations, and expr will
then be evaluated in the extended environment. The result of
expr will be returned as the result of the procedure call.
(lambda (x) (+ x x)) --> #<PROCEDURE>
((lambda (x) (+ x x)) 4) --> 8
(define reverse-subtract
(lambda (x y) (- y x))) --> reverse-subtract
(reverse-subtract 7 10) --> 3
(define foo
(let ((x 4))
(lambda (y) (+ x y)))) --> foo
(foo 6) --> 10
(lambda (var1 ...) expr1 expr2 ...) essential special form
Equivalent to (lambda (var1 ...) (begin expr1 expr2 ...)).
(lambda var expr1 expr2 ...) essential special form
Returns a procedure that when later called with some arguments
will bind var to a fresh location, convert the sequence of
actual arguments into a list, and store that list in the binding
of var.
((lambda x x) 3 4 5 6) --> (3 4 5 6)
One last variation on the formal argument list provides for a
so-called rest argument. If a space/dot/space sequence precedes
the last argument in the formal argument list, then the value
stored in the binding of the last formal argument will be a list
of the actual arguments left over after all the other actual
arguments have been matched up against the formal arguments.
((lambda (x y . z) z) 3 4 5 6) --> (5 6)
(if condition consequent alternative) essential special form
(if condition consequent) essential special form
First evaluates condition. If it yields a true value (see
section II.2), then consequent is evaluated and its value is
returned. Otherwise alternative is evaluated and its value is
returned. If no alternative is specified, then the if
expression is evaluated only for its effect, and the result of
the expression is unspecified.
(if (>? 3 2) 'yes 'no) --> yes
(if (>? 2 3) 'yes 'no) --> no
(if (>? 3 2) (- 3 2) (+ 3 2)) --> 1
(cond clause1 clause2 ...) essential special form
Each clause must be a list of one or more expressions. The
first expression in each clause is a boolean expression that
serves as the guard for the clause. The guards are evaluated in
order until one of them evaluates to a true value (see section
II.2). When a guard evaluates true, then the remaining
expressions in its clause are evaluated in order, and the result
of the last expression in the selected clause is returned as the
result of the entire expression. If the selected clause
contains only the guard, then the value of the guard is returned
as the result. If all tests evaluate to false values, then the
result of the conditional expression is unspecified.
(cond ((>? 3 2) 'greater)
((<? 3 2) 'less)) --> greater
The special keyword else may be used as a guard to obtain the
effect of an otherwise clause.
(cond ((>? 3 3) 'greater)
((<? 3 3) 'less)
(else 'equal)) --> equal
The above forms for the clauses are essential. Some
implementations support yet another form of clause such that
(cond (form1 => form2) ...)
is equivalent to
(let ((form1←result form1)
(thunk2 (lambda () form2))
(thunk3 (lambda () (cond ...))))
(if form1←result
((thunk2) form1←result)
(thunk3)))
(case expr clause1 clause2 ...) special form
Each clause is a list whose first element is a selector followed
by one or more expressions. Each selector should be a list of
values. The selectors are not evaluated. Instead expr is
evaluated and its result is compared against successive
selectors using the memv procedure until a match is found. Then
the expressions in the selected clause are evaluated from left
to right and the result of the last expression in the clause is
returned as the result of the case expression. If no selector
matches then the result of the case expression is unspecified.
(case (* 2 3)
((2 3 5 7) 'prime)
((1 4 6 8 9) 'composite)) --> composite
(case (car '(c d))
((a) 'a)
((b) 'b)) --> unspecified
The special keyword else may be used as a selector to obtain the
effect of an otherwise clause.
(case (car '(c d))
((a e i o u) 'vowel)
((y) 'y)
(else 'consonant)) --> consonant
(and expr1 ...) special form
Evaluates the exprs from left to right, returning false as soon
as one evaluates to a false value (see section II.2). Any
remaining expressions are not evaluated. If all the expressions
evaluate to true values, the value of the last expression is
returned.
(and (=? 2 2) (>? 2 1)) --> #!true
(and (=? 2 2) (<? 2 1)) --> #!false
(and 1 2 'c '(f g)) --> (f g)
(or expr1 ...) special form
Evaluates the exprs from left to right, returning the value of
the first expr that evaluates to a true value (see section
II.2). Any remaining expressions are not evaluated. If all
expressions evaluate to false values, false is returned.
(or (=? 2 2) (>? 2 1)) --> #!true
(or (=? 2 2) (<? 2 1)) --> #!true
(or #!false #!false #!false) --> #!false
(or (memq 'b '(a b c)) (/ 3 0)) --> (b c)
(let ((var1 form1) ...) expr1 expr2 ...) essential special form
Evaluates the forms in the current environment (in some
unspecified order), binds the vars to fresh locations holding
the results, and then evaluates the exprs in the extended
environment, returning the value of the last one. Each binding
of a var has expr1 expr2 ... as its region.
(let ((x 2)
(y 3))
(* x y)) --> 6
(let ((x 2)
(y 3))
(let ((foo (lambda (z)
(+ x y z)))
(x 7))
(foo 4))) --> 9
let and letrec give Scheme a block structure. The difference
between let and letrec is that in a let the forms are not within
the regions of the vars being bound. See letrec.
Some implementations of Scheme permit a "named let" syntax in
which
(let name ((var1 form1) ...) expr1 expr2 ...)
is equivalent to
((rec name (lambda (id1 ...) expr1 expr2 ...))
form1 ...)
(let* ((var1 form1) ...) expr1 expr2 ...) special form
Similar to let, but the bindings are performed sequentially from
left to right and the region of a binding indicated by (var
form) is that part of the let* expression to the right of the
binding. Thus the second binding is done in an environment in
which the first binding is visible, and so on.
(letrec ((var1 form1) ...) expr1 expr2 ...)essential special form
Binds the vars to fresh locations holding undefined values,
evaluates the forms in the resulting environment (in some
unspecified order), assigns to each var the result of the
corresponding form, evaluates the exprs sequentially in the
resulting environment, and returns the value of the last expr.
Each binding of a var has the entire letrec expression as its
region, making it possible to define mutually recursive
procedures. See let.
(letrec ((x 2)
(y 3))
(letrec ((foo (lambda (z)
(+ x y z)))
(x 7))
(foo 4))) --> 14
(letrec ((even? (lambda (n)
(if (zero? n)
#!true
(odd? (-1+ n)))))
(odd? (lambda (n)
(if (zero? n)
#!false
(even? (-1+ n))))))
(even? 88))
--> #!true
One restriction on letrec is very important: it must be possible
to evaluate each form without referring to the value of a var.
If this restriction is violated, then the effect is undefined,
and an error may be signalled during evaluation of the forms.
The restriction is necessary because Scheme uses call by value
rather than call by name. In the most common uses of letrec,
all the forms are lambda expressions and the restriction is
satisfied automatically.
(rec var expr) special form
Equivalent to (letrec ((var expr)) var). rec is useful for
defining self-recursive procedures.
(named-lambda (name var1 ...) expr ...) special form
Equivalent to
(rec name (lambda (var1 ...) expr ...))
Rationale: Some implementatations may find it easier to provide
good debugging information when named-lambda is used instead of
rec.
(define var expr) essential special form
When typed at top level (so that it is not nested within any
other expression), this form has essentially the same effect as
(set! var expr) if var is bound. If var is not bound, however,
then the define form will bind var before performing the
assignment, whereas it would be an error to perform a set! on an
unbound identifier. The value returned by a define form is not
specified.
(define add3 (lambda (x) (+ x 3))) --> unspecified
(add3 3) --> 6
(define first car) --> unspecified
(first '(1 2)) --> 1
The semantics just described is essential. Some implementations
also allow define expressions to appear at the beginning of the
body of a lambda, named-lambda, let, let*, or letrec expression.
Such expressions are known as internal definitions as opposed to
the top level definitions described above. The variable defined
by an internal definition is local to the body of the lambda,
named-lambda, let, let*, or letrec expression. That is, var is
bound rather than assigned, and the region set up by the binding
is the entire body of the lambda, named-lambda, let, let*, or
letrec expression. For example,
(let ((x 5))
(define foo
(lambda (y)
(bar x y)))
(define bar
(lambda (a b)
(+ (* a b) a)))
(foo (+ x 3))) --> 45
Internal definitions can always be converted into an equivalent
letrec expression. For example, the let expression in the above
example is equivalent to
(let ((x 5))
(letrec ((foo (lambda (y)
(bar x y)))
(bar (lambda (a b)
(+ (* a b) a))))
(foo (+ x 3))))
(define (var0 var1 ...) expr1 expr2 ...) special form
(define (form var1 ...) expr1 expr2 ...) special form
The first form, where var0 is an identifier, is equivalent to
(define var0 (rec var0 (lambda (var1 ...) expr1 expr2 ...))).
The second form, where form is a list, is sometimes convenient
for defining a procedure that returns another procedure as its
result. It is equivalent to
(define form (lambda (var1 ...) expr1 expr2 ...)).
(define! var expr) special form
If var is bound, then the define! form is equivalent to the
corresponding set!. If var is unbound, however, define! binds
var in the global environment before performing the assignment.
Rationale: This makes sense only for implementations with a
distinguished global environment.
(defrec! var expr) special form
Equivalent to (define! var (rec var expr)).
(set! var expr) essential special form
Stores the value of expr in the location to which var is bound.
expr is evaluated but var is not. The result of the set!
expression is unspecified.
(set! x 4) --> unspecified
(1+ x) --> 5
Rationale: set! expressions are Scheme's assignment statements.
Assignment statements are seldom used in good Scheme code.
Their major uses are to initialize variables accessed
interactively and to construct objects with local state.
(begin expr1 expr2 ...) essential special form
Evaluates the exprs sequentially from left to right and returns
the value of the last expr. Used to sequence side effects such
as input and output.
(begin (set! x 5)
(1+ x)) --> 6
Also
(begin (display "4 plus 1 equals ")
(display (1+ 4)))
prints
4 plus 1 equals 5
A number of special forms such as lambda and letrec implicitly
treat their bodies as begin expressions.
(sequence expr1 expr2 ...) special form
sequence is synonymous with begin.
Rationale: sequence was used in the Abelson and Sussman text,
but it should not be used in new code.
(do ((var1 init1 step1) ...) special form
(test expr1 ...)
stmt1 ...)
The do special form is an extremely general albeit complex
iteration macro. Each var must be an identifier and each init
and step must be expressions. The init expressions are
evaluated (in some unspecified order), the vars are bound to
fresh locations, the results of the init expressions are stored
in the bindings of the vars, and then the iteration phase
begins.
Each iteration begins by evaluating test; if the result is false
(see section II.2), then the stmts are evaluated in order for
effect, the steps are evaluated (in some unspecified order), the
results of the step expressions are stored in the bindings of
the vars, and the next iteration begins.
If test evaluates true, then the exprs are evaluated from left
to right and the value of the last expr is returned as the value
of the do expression. If no exprs are present, then the value
of the do expression is unspecified.
The region set up by the binding of a var consists of the entire
do expression except for the inits.
A step may be omitted, in which case the corresponding var is
not updated. When the step is omitted the init may be omitted
as well, in which case the initial value is not specified.
(do ((vec (make-vector 5))
(i 0 (1+ i)))
((=? i 5) vec)
(vector-set! vec i i)) --> #(0 1 2 3 4)
(let ((x '(1 3 5 7 9)))
(do ((x x (cdr x))
(sum 0 (+ sum (car x))))
((null? x) sum))) --> 25
The do special form is essentially the same as the do macro in
Common Lisp. The main difference is that in Scheme the
identifier return is not bound; programmers that want to bind
return as in Common Lisp must do so explicitly (see
call-with-current-continuation).
`pattern macro special form
The backquote special form is useful for constructing a list
structure when most but not all of the desired structure is
known in advance. If no commas appear within the pattern, the
result of evaluating `pattern is equivalent (in the sense of
equal?) to the result of evaluating 'pattern. If a comma
appears within the pattern, however, the expression following
the comma is evaluated and its result is inserted into the
structure instead of the comma and the expression. If a comma
appears followed immediately by an at-sign (@), then the
following expression must evaluate to a list; the opening and
closing parentheses of the list are then "stripped away" and the
elements of the list are inserted in place of the
comma/at-sign/expression sequence.
`(a ,(+ 1 2) ,@(mapcar 1+ '(4 5 6)) b) --> (a 3 5 6 7 b)
`(((foo ,(- 10 3)) ,@(cdr '(c)) cons)) --> (((foo 7) cons))
Scheme does not have any standard facility for defining new
special forms.
Rationale: The ability to define new special forms creates
numerous problems. All current implementations of Scheme have
macro facilities that solve those problems to one degree or
another, but the solutions are quite different and it isn't
clear at this time which solution is best, or indeed whether any
of the solutions are truly adequate. Rather than standardize,
we are encouraging implementations to continue to experiment
with different solutions.
The main problems with traditional macros are: They must be
defined to the system before any code using them is loaded; this
is a common source of obscure bugs. They are usually global;
macros can be made to follow lexical scope rules as in Common
Lisp's macrolet, but many people find the resulting scope rules
confusing. Unless they are written very carefully, macros are
vulnerable to inadvertant capture of free variables; to get
around this, for example, macros may have to generate code in
which procedure values appear as quoted constants. There is a
similar problem with keywords if the keywords of special forms
are not reserved. If keywords are reserved, then either macros
introduce new reserved words, invalidating old code, or else
special forms defined by the programmer do not have the same
status as special forms defined by the system.
!II.2. Booleans
The standard boolean objects for truth and falsity are written
as #!true and #!false. What really matters, though, are the
objects that the Scheme conditional expressions (if, cond, and,
or, do) will treat as though they were true or false. The
phrase "a true value" (or sometimes just "true") means any
object treated as true by the conditional expressions, and the
phrase "a false value" (or "false") means any object treated as
false by the conditional expressions.
Of all the standard Scheme values, only #!false and the empty
list count as false in conditional expressions. #!true, pairs
(and therefore lists), symbols, numbers, strings, vectors, and
procedures all count as true.
The empty list counts as false for historical reasons only, and
programs should not rely on this because future versions of
Scheme will probably do away with this nonsense.
Programmers accustomed to other dialects of Lisp should beware
that Scheme has already done away with the nonsense that
identifies the empty list with the symbol nil.
#!false essential constant
#!false is the boolean value for falsity. The #!false object is
self-evaluating. That is, it does not need to be quoted in
programs.
'#!false --> #!false
#!false --> #!false
#!true essential constant
#!true is the boolean value for truth. The #!true object is
self-evaluating, and does not need to be quoted in programs.
(not obj) essential procedure
Returns #!true if obj is false and returns #!false otherwise.
nil variable
t variable
As a crutch for programmers accustomed to other dialects of
Lisp, some implementations provide variables nil and t whose
initial values are #!false and #!true respectively. These
variables should not be used in new code.
!II.3. Equivalence predicates
A predicate is a procedure that always returns #!true or
#!false. Of the equivalence predicates described in this
section, eq? is the most discriminating while equal? is the most
liberal. eqv? is very slightly less discriminating than eq?.
(eq? obj1 obj2) essential procedure
Returns #!true if obj1 is identical in all respects to obj2,
otherwise returns #!false. If there is any way at all that a
∂19-Mar-85 0505 @MIT-MC:forwarder@CSNET-SH.ARPA Message a011267 LONG message - part 2
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 19 Mar 85 05:04:57 PST
Received: from CSNET-SH by MIT-MC.ARPA; 19 MAR 85 07:56:39 EST
To: scheme@MIT-MC.ARPA
Subject: Message a011267 LONG message - part 2
Reply-to: cic@CSNET-SH.ARPA
Date: 19 Mar 85 07:51:18 EST (Tue)
From: "Charlotte D. Mooers" <postmaster@CSNET-SH.ARPA>
user can distinguish obj1 and obj2, then eq? will return
#!false. On the other hand, it is guaranteed that objects
maintain their identity despite being fetched from or stored
into variables or data structures.
The notion of identity used by eq? is stronger than the notions
of equivalence used by the eqv? and equal? predicates. The
constants #!true and #!false are identical to themselves and are
different from everything else, except that in some
implementations the empty list is identical to #!false for
historical reasons. Two symbols are identical if they print the
same way (except that some implementations may have "uninterned
symbols" that violate this rule). For structured objects such
as pairs and vectors the notion of sameness is defined in terms
of the primitive mutation procedures defined on those objects.
For example, two pairs are the same if and only if a set-car!
operation on one changes the car field of the other. The rules
for identity of numbers are extremely implementation-dependent
and should not be relied on.
Generally speaking, the equal? procedure should be used to
compare lists, vectors, and arrays. The string-equal? procedure
should be used to compare strings, and the =? procedure should
be used to compare numbers. The eqv? procedure is just like eq?
except that it is more inclined to say that two numbers are the
same.
(eq? 'a 'a) --> #!true
(eq? 'a 'b) --> #!false
(eq? '(a) '(a)) --> unspecified
(eq? "a" "a") --> unspecified
(eq? 2 2) --> unspecified
(eq? (cons 'a 'b) (cons 'a 'b)) --> #!false
(let ((x (read)))
(eq? (cdr (cons 'b x)) x))) --> #!true
(eqv? obj1 obj2) essential procedure
eqv? is just like eq? except that if obj1 and obj2 are exact
numbers then eqv? is guaranteed to return #!true if obj1 and
obj2 are equal according to the =? procedure.
(eq? 100000 100000) --> unspecified
(eqv? 100000 100000) --> #!true
See section II.6 for a discussion of exact numbers.
(equal? obj1 obj2) essential procedure
Returns #!true if obj1 and obj2 are identical objects or if they
are equivalent numbers, lists, strings, vectors, or arrays. Two
objects are generally considered equivalent if they print the
same. equal? may not terminate if its arguments are circular
data structures.
(equal? 'a 'a) --> #!true
(equal? '(a) '(a)) --> #!true
(equal? '(a (b) c) '(a (b) c)) --> #!true
(equal? "abc" "abc") --> #!true
(equal? 2 2) --> #!true
(equal? (make-vector 5 'a)
(make-vector 5 'a)) --> #!true
equal? is a blunderbuss of a predicate and should not be used
when a less liberal or more specific predicate will suffice.
!II.4. Pairs and lists
Lists are Lisp's -- and therefore Scheme's -- characteristic
data structures. Even Lisp and Scheme programs are lists.
The empty list is a special object that is written as an opening
parenthesis followed by a closing parenthesis:
()
The empty list has no elements, and its length is zero. The
empty list is not a pair.
Larger lists are built out of pairs. A pair (sometimes called a
"dotted pair") is a record structure with two fields called the
car and cdr fields (for historical reasons). Pairs are created
by the constructor procedure cons. The car and cdr fields are
accessed by the selector procedures car and cdr. The car and
cdr fields are assigned by the mutator procedures set-car! and
set-cdr!.
The most general notation used for Scheme pairs is the "dotted"
notation (c1 . c2) where c1 is the value of the car field and
c2 is the value of the cdr field. For example
(4 . 5)
is a pair whose car is 4 and whose cdr is 5.
The dotted notation is not often used, because more streamlined
notations exist for the common case where the cdr is the empty
list or a pair. (c1 . ()) is usually written as (c1). (c1 .
(c2 . c3)) is usually written as (c1 c2 . c3). Usually these
special notations permit a structure to be written without any
dotted pair notation at all. For example
(a . (b . (c . (d . (e . ())))))
would normally be written as
(a b c d e)
When all the dots can be made to disappear as in the example
above, the entire structure is called a proper list. Proper
lists are so common that when people speak of a list, they
usually mean a proper list. For those who prefer an inductive
definition:
1. The empty list is a proper list.
2. If l is a proper list, then any pair whose cdr is
l is also a proper list.
3. There are no other proper lists.
A proper list is therefore either the empty list or a pair from
which the empty list can be obtained by applying the cdr
procedure a finite number of times.
Whether a given pair is a proper list depends upon what is
stored in the cdr field. When the set-cdr! procedure is used,
an object can be a proper list one moment and not the next:
(define x '(a b c)) --> x
(define y x) --> y
(set-cdr! x 4) --> unspecified
x --> (a . 4)
(eq? x y) --> #!true
y --> (a . 4)
A pair object, on the other hand, will always be a pair object.
It is often convenient to speak of a homogeneous (proper) list
of objects of some particular data type, as for example (1 2 3)
is a list of integers. To be more precise, suppose D is some
data type. (Any predicate defines a data type consisting of
those objects of which the predicate is true.) Then
1. The empty list is a list of D.
2. If l is a list of D, then any pair
whose cdr is l and whose car satisfies the data
type D is also a list of D.
3. There are no other lists of D.
(pair? obj) essential procedure
Returns #!true if obj is a pair, otherwise returns #!false.
(pair? '(a . b)) --> #!true
(pair? '(a b c)) --> #!true
(pair? '()) --> #!false
(pair? '#(a b)) --> #!false
(cons obj1 obj2) essential procedure
Returns a newly allocated pair whose car is obj1 and whose cdr
is obj2. The pair is guaranteed to be different (in the sense
of eq?) from every existing object.
(cons 'a '()) --> (a)
(cons '(a) '(b c d)) --> ((a) b c d)
(cons "a" '(b c)) --> ("a" b c)
(cons 'a 3) --> (a . 3)
(cons '(a b) 'c) --> ((a b) . c)
(car pair) essential procedure
Returns the contents of the car field of pair. pair must be a
pair. Note that taking the car of the empty list is an error.
(car '(a b c)) --> a
(car '((a) b c d)) --> (a)
(car '(1 . 2)) --> 1
(car '()) --> error
(cdr pair) essential procedure
Returns the contents of the cdr field of pair. pair must be a
pair. Note that taking the cdr of the empty list is an error.
(cdr '((a) b c d)) --> (b c d)
(cdr '(1 . 2)) --> 2
(cdr '()) --> error
(set-car! pair obj) essential procedure
Stores obj in the car field of pair. pair must be a pair. The
value returned by set-car! is unspecified. This procedure can
be very confusing if used indiscriminately.
(set-cdr! pair obj) essential procedure
Stores obj in the cdr field of pair. pair must be a pair. The
value returned by set-cdr! is unspecified. This procedure can
be very confusing if used indiscriminately.
(caar pair) essential procedure
(cadr pair) essential procedure
(cdar pair) essential procedure
(cddr pair) essential procedure
(caaar pair) essential procedure
(caadr pair) essential procedure
(cadar pair) essential procedure
(caddr pair) essential procedure
(cdaar pair) essential procedure
(cdadr pair) essential procedure
(cddar pair) essential procedure
(cdddr pair) essential procedure
(caaaar pair) essential procedure
(caaadr pair) essential procedure
(caadar pair) essential procedure
(caaddr pair) essential procedure
(cadaar pair) essential procedure
(cadadr pair) essential procedure
(caddar pair) essential procedure
(cadddr pair) essential procedure
(cdaaar pair) essential procedure
(cdaadr pair) essential procedure
(cdadar pair) essential procedure
(cdaddr pair) essential procedure
(cddaar pair) essential procedure
(cddadr pair) essential procedure
(cdddar pair) essential procedure
(cddddr pair) essential procedure
These procedures are compositions of car and cdr, where for
example caddr could be defined by
(define caddr (lambda (x) (car (cdr (cdr x)))))
'() essential constant
#!null constant
() is the empty list. The #!null notation does not have to be
quoted in programs. The '() notation must include the quote,
however, because otherwise it would be a procedure call without
a procedure expression.
Rationale: Because many current Scheme interpreters deal with
expressions as list structures rather than as character strings,
they will treat an unquoted () as though it were quoted. It is
entirely possible, however, that some implementations of Scheme
will be able to detect this error.
(null? obj) essential procedure
Returns #!true if obj is the empty list, otherwise returns
#!false.
(list obj1 ...) essential procedure
Returns a list of its arguments.
(list 'a (+ 3 4) 'c) --> (a 7 c)
(length plist) essential procedure
Returns the length of plist, which must be a proper list.
(length '()) --> 0
(length '(a b c)) --> 3
(length '(a (b) (c d e))) --> 3
(append plist1 plist2) essential procedure
(append plist ...) procedure
Returns a list consisting of the elements of the first plist
followed by the elements of the other plists. All plists should
be proper lists.
(append '(x) '(y)) --> (x y)
(append '(a) '(b c d)) --> (a b c d)
(append '(a (b)) '((c))) --> (a (b) (c))
(append! plist ...) procedure
Like append but may side effect its arguments.
(reverse plist) procedure
Returns a list consisting of the elements of plist in reverse
order. plist must be a proper list.
(reverse '(a b c)) --> (c b a)
(reverse '(a (b c) d (e (f)))) --> ((e (f)) d (b c) a)
(list-ref x n) procedure
Returns the car of (list-tail x n).
(list-tail x n) procedure
Returns the sublist of x obtained by omitting the first n
elements. Could be defined by
(define list-tail
(lambda (x n)
(if (zero? n)
x
(list-tail (cdr x) (- n 1)))))
(last-pair x) procedure
Returns the last pair in the nonempty list x. Could be defined
by
(define last-pair
(lambda (x)
(if (pair? (cdr x))
(last-pair (cdr x))
x)))
(memq obj plist) essential procedure
(memv obj plist) essential procedure
(member obj plist) essential procedure
Finds the first occurrence of obj in the proper list plist and
returns the first sublist of plist beginning with obj. If obj
does not occur in plist, returns #!false. memq uses eq? to
compare obj with the elements of plist, while memv uses eqv? and
member uses equal?.
(memq 'a '(a b c)) --> (a b c)
(memq 'b '(a b c)) --> (b c)
(memq 'a '(b c d)) --> #!false
(memq (list 'a) '(b (a) c)) --> #!false
(memq 101 '(100 101 102)) --> unspecified
(memv 101 '(100 101 102)) --> (101 102)
(member (list 'a) '(b (a) c)) --> ((a) c)
(assq obj alist) essential procedure
(assv obj alist) essential procedure
(assoc obj alist) essential procedure
alist must be a proper list of pairs. Finds the first pair in
alist whose car field is obj and returns that pair. If no pair
in alist has obj as its car, returns #!false. assq uses eq? to
compare obj with the car fields of the pairs in alist, while
assv uses eqv? and assoc uses equal?.
(assq 'a '((a 1) (b 2) (c 3))) --> (a 1)
(assq 'b '((a 1) (b 2) (c 3))) --> (b 2)
(assq 'd '((a 1) (b 2) (c 3))) --> #!false
(assq '(a) '(((a)) ((b)) ((c)))) --> #!false
(assq 5 '((2 3) (5 7) (11 13))) --> unspecified
(assv 5 '((2 3) (5 7) (11 13))) --> (5 7)
(assoc '(a) '(((a)) ((b)) ((c)))) --> ((a))
Rationale: memq, memv, member, assq, assv, assoc do not have
question marks in their names because they return useful values
rather than just #!true.
!II.5. Symbols
Symbols are objects whose usefulness rests entirely on the fact
that two symbols are identical (in the sense of eq?) if and only
if their names are spelled the same way. This is exactly the
property that is needed for identifiers in programs, and so most
implementations of Scheme use them internally for that purpose.
Programmers may also use symbols as they use enumerated types in
Pascal.
The rules for writing a symbol are the same as the rules for
writing an identifier (see section I.2). As with identifiers,
different implementations of Scheme use slightly different
rules, but it is always the case that a sequence of characters
that contains no special characters and begins with a character
that cannot begin a number is taken to be a symbol; in addition
+, -, 1+, and -1+ are symbols.
The case in which a symbol is written in unimportant. Some
implementations of Scheme convert any upper case letters to
lower case, and others convert lower case to upper case.
It is guaranteed that any symbol that has been read using the
read procedure and subsequently written out using the write
procedure will read back in as the identical symbol (in the
sense of eq?). The string->symbol procedure, however, can
create symbols for which the write/read invariance may not hold
because their names contain special characters or letters in the
non-standard case.
Rationale: Some implementations of Lisp have a feature known as
"slashification" in order to guarantee write/read invariance for
all symbols, but historically the most important use of this
feature has been to compensate for the lack of a string data
type. Some implementations have "uninterned symbols", which
defeat write/read invariance even in implementations with
slashification and also generate exceptions to the rule that two
symbols are the same if and only if their names are spelled the
same. It is questionable whether these features are worth their
complexity, so they are not standard in Scheme.
(symbol? obj) essential procedure
Returns #!true is obj is a symbol, otherwise returns #!false.
(symbol? 'foo) --> #!true
(symbol? (car '(a b))) --> #!true
(symbol? "bar") --> #!false
(symbol->string symbol) essential procedure
Returns the name of symbol as a string. symbol->string performs
no case conversion. See string->symbol. The following examples
assume the read procedure converts to lower case:
(symbol->string 'flying-fish) --> "flying-fish"
(symbol->string 'Martin) --> "martin"
(symbol->string
(string->symbol "Malvina")) --> "Malvina"
(string->symbol string) essential procedure
Returns the symbol whose name is string. string->symbol can
create symbols with special symbols or upper case letters in
their names, but it is usually a bad idea to create such symbols
because in some implementations of Scheme they cannot be read as
themselves. See symbol->string.
'mISSISSIppi --> mississippi
(string->symbol "mISSISSIppi") --> mISSISSIppi
(eq? 'bitBlt
(string->symbol "bitBlt")) --> #!false
(eq? 'JollyWog
(string->symbol
(symbol->string 'JollyWog))) --> #!true
(string-equal?
"K. Harper, M.D."
(symbol->string
(string->symbol
"K. Harper, M.D."))) --> #!true
!II.6. Numbers (part 1)
Numerical computation has traditionally been neglected by the
Lisp community. Until Common Lisp there has been no carefully
thought out strategy for organizing numerical computation, and
with the exception of the MacLisp system there has been little
effort to execute numerical code efficiently. We applaud the
excellent work of the Common Lisp committee and we accept many
of their recommendations. In some ways we simplify and
generalize their proposals in a manner consistent with the
purposes of Scheme.
Scheme's numerical operations treat numbers as abstract data, as
independent of the machine representation as is possible. Thus,
the casual user should be able to write simple programs without
having to know that the implementation may use fixed-point,
floating-point, and perhaps other representations for his data.
Unfortunately, this illusion of uniformity can only be sustained
approximately -- the implementation of numbers will leak out of
our abstraction whenever the user must be in control of
precision, or accuracy, or when he must construct especially
efficient computations. Thus we also must provide escape
mechanisms so that a sophisticated programmer can exercise more
control of the execution of his code and the representation of
his data when it is essential to do so.
We separate out several apparently related issues of
representation -- the abstract numbers, their machine
representation, and the input/output formats of the symbolic
expressions which denote numerical constants. We will use
mathematical words such as NUMBER, COMPLEX, REAL, RATIONAL, and
INTEGER for properties of the abstract numbers, data-structure
names such as FIXNUM, BIGNUM, RATNUM, and FLONUM for machine
representations, and names like INT, FIX, FLO, SCI, RAT, POLAR,
and RECT for input/output formats.
Notations for numbers are the subject of section II.7.
Numbers.
A Scheme system provides data of type NUMBER, which is the most
general numerical type supported by that system. NUMBER is
likely to be a complicated union type implemented in terms of
FIXNUMs, BIGNUMS, FLONUMS, etc. but this should not be apparent
to a naive user. What the user sees is that the obvious
operations on numbers produce the mathematically expected
results, within the limits of the implementation. Thus if the
user divides 3 by 2, he should get something like 1.5 (or, the
exact fraction 3/2). If he adds that result to itself, and if
the implementation can swing it, he should get an exact 3.
Mathematically, numbers may be arranged into a tower of subtypes
with natural projections and injections relating adjacent
members of the tower:
NUMBER
COMPLEX
REAL
RATIONAL
INTEGER
We impose a uniform rule of downward coercion -- a number of one
type is also of a lower type if the injection (up) of the
projection (down) of a number leaves the number unchanged.
Since this tower is a real mathematical entity, Scheme provides
predicates and procedures that access the tower.
Not all Scheme implementations must provide the whole tower, but
they are required to implement a coherent subset, consistent
with the purposes of Scheme.
Exactness.
Numbers are either EXACT or INEXACT. A number is exact if it
was derived from EXACT numbers using only EXACT operations. A
number is INEXACT if it models a quantity known only
approximately, if it was derived using INEXACT ingredients, or
if it was derived using INEXACT operations. Thus INEXACTness is
a contagious property of a number. Some operations, such as the
square root (of non-square numbers) must be INEXACT because of
the finite precision of our representations. Other operations
are inexact because of implementation requirements. We
emphasize that exactness is independent of the position of the
number on the tower. It is perfectly possible to have an
INEXACT INTEGER or an EXACT REAL; 355/113 may be an EXACT
RATIONAL or it may be an INEXACT RATIONAL approximation to pi,
depending on the application.
Operationally, it is the system's responsibility to combine
EXACT numbers using exact methods, such as infinite precision
integer and rational arithmetic, where possible. An
implementation may not be able to do this (if it does not use
infinite precision integers and rationals), but if a number
becomes inexact for implementation reasons there is probably an
important error condition, such as integer overflow, to be
reported. Arithmetic on INEXACT numbers is not so constrained.
The system may use floating point and other flaky representation
strategies for INEXACT numbers. This is not to say that
implementors need not use the best known algorithms for INEXACT
computations -- only that high-quality approximate methods are
allowed. In a system which cannot explicitly distinguish exact
from inexact numbers the system must do its best to maintain
precision. Scheme systems must not burden users with numerical
operations described in terms of hardware and operating-system
dependent representations such as FIXNUM and FLONUM. These
representation issues should not be germane to the user's
problems.
We highly recommend that the IEEE 32-bit and 64-bit
floating-point standards be adopted for implementations that use
floating-point internal representations. To minimize loss of
precision we adopt the following rules: If an implementation
uses several different sizes of floating-point formats, the
results of any operation with a floating-point result must be
expressed in the largest format used to express any of the
floating-point arguments to that operation. It is desirable
(but not required) for potentially irrational operations such as
sqrt, when applied to EXACT arguments, to produce EXACT answers
when that is possible (eg. sqrt[4]=2, exactly). If an EXACT
number (or an INEXACT number represented as a FIXNUM, a BIGNUM,
or a RATNUM) is operated upon so as to produce an INEXACT result
(as by sqrt), and if the result is represented as a FLONUM, then
the largest available format FLONUM must be used; but if the
result is expressed as a RATNUM then the rational approximation
must have at least as much precision as the largest available
format FLONUM. (Note that this last rule is much stronger than
that used in Common Lisp. Consider the result of the square
root of a rational, for example.)
Numerical operations.
Scheme provides the usual set of operations for manipulating
numbers. In general, numerical operations require numerical
arguments. For succintness we let the following meta-symbols
range over the indicated types of object in our descriptions,
and we let these meta-symbols specify the types of the arguments
to numeric operations. It is an error for an operation to be
presented with an argument that it is not specified to handle.
obj any arbitrary object
z, z1, ... zi, ... complex, real, rational, integer
x, x1, ... xi, ... real, rational, integer
q, q1, ... qi, ... rational, integer
n, n1, ... ni, ... integer
(number? obj) essential procedure
(complex? obj) essential procedure
(real? obj) essential procedure
(rational? obj) essential procedure
(integer? obj) essential procedure
These numerical type predicates can be applied to any kind of
argument. They return true if the object is of the named type.
In general, if a type predicate is true of a number then all
higher type predicates are also true of that number. Not every
system supports all of these types; it is entirely possible to
have a Scheme system that has only INTEGERs. Nonetheless every
implementation of Scheme must have all of these predicates.
(zero? z) essential procedure
(positive? x) essential procedure
(negative? x) essential procedure
(odd? n) essential procedure
(even? n) essential procedure
(exact? z) essential procedure
(inexact? z) essential procedure
These numerical predicates test a number for a particular
property. They return a boolean value.
(= z1 z2) essential procedure
(=? z1 z2) essential procedure
(= z1 z2 z3 ...) procedure
(=? z1 z2 z3 ...) procedure
(< x1 x2) essential procedure
(<? x1 x2) essential procedure
(< x1 x2 x3 ...) procedure
(<? x1 x2 x3 ...) procedure
(> x1 x2) essential procedure
(>? x1 x2) essential procedure
(> x1 x2 x3 ...) procedure
(>? x1 x2 x3 ...) procedure
(<= x1 x2) essential procedure
(<=? x1 x2) essential procedure
(<= x1 x2 x3 ...) procedure
(<=? x1 x2 x3 ...) procedure
(>= x1 x2) essential procedure
(>=? x1 x2) essential procedure
(>= x1 x2 x3 ...) procedure
(>=? x1 x2 x3 ...) procedure
The numerical comparison predicates have redundant names (with
and without the terminal "?") to make all populations happy.
They optionally take many arguments, as in Common Lisp, to
facilitate range checks. These procedures return true if their
arguments are (respectively): numerically equal, monotonically
increasing, monotonically decreasing, monotonically
nondecreasing, or monotonically nonincreasing. Warning: On
INEXACT numbers equality tests will give unreliable results;
other numerical comparisons are only heuristically useful (ask a
numerical analyst about this!).
(max x1 x2) essential procedure
(max x1 x2 ...) procedure
(min x1 x2) essential procedure
(min x1 x2 ...) procedure
Returns the maximum or minimum of its arguments, respectively.
(+ z1 z2) essential procedure
(+ z1 ...) procedure
(* z1 z2) essential procedure
(* z1 ...) procedure
These procedures return the sum or product of their arguments.
(+ 3 4) --> 7
(+ 3) --> 3
(+) --> 0
(* 4) --> 4
(*) --> 1
(- z1 z2) essential procedure
(- z1 z2 ...) procedure
(/ z1 z2) essential procedure
(/ z1 z2 ...) procedure
With two or more arguments, these procedures return the
difference or (complex) quotient of their arguments, associating
to the left. With one argument, however, they return the
additive or multiplicative inverse of their argument.
(- 3 4) --> -1
(- 3 4 5) --> -6
(- 3) --> -3
(/ 3 4 5) --> 3/20
(/ 3) --> 1/3
(1+ z) procedure
(-1+ z) procedure
These procedures return the result of adding or subtracting 1 to
their argument.
(abs z) essential procedure
Returns the magnitude of its argument.
(abs -7) --> 7
(abs -3+4i) --> 5
(quotient n1 n2) essential procedure
(remainder n1 n2) essential procedure
(modulo n1 n2) procedure
In general, these are intended to implement number-theoretic
(integer) division, where for positive integers n1 and n2 if n3
and n4 are integers such that
n1 = n3 * n2 + n4 and 0 <= n4 < n2
then
(quotient n1 n2) --> n3
(remainder n1 n2) --> n4
(modulo n1 n2) --> n4
remainder and modulo differ on negative arguments as do the
Common Lisp rem and mod procedures -- the remainder always has
the sign of the dividend, the modulo always has the sign of the
divisor:
(modulo 13 4) --> 1
(remainder 13 4) --> 1
(modulo -13 4) --> 3
(remainder -13 4) --> -1
(modulo 13 -4) --> -3
(remainder 13 -4) --> 1
(modulo -13 -4) --> -1
(remainder -13 -4) --> -1
(gcd n1 ...) procedure
(lcm n1 ...) procedure
These procedures return the greatest common divisor or least
common multiple of their arguments. The arguments to lcm should
be nonzero. The result is always non-negative.
(gcd 32 -36) --> 4
(gcd) --> 0
(lcm 32 -36) --> 288
(lcm) --> 1
(floor x) procedure
(ceiling x) procedure
(truncate x) procedure
(round x) procedure
(rationalize x y) procedure
(rationalize x) procedure
These procedures create integers and rationals. Their results
are not EXACT -- in fact, their results are clearly INEXACT,
though they can be made EXACT with an explicit exactness
coercion.
floor returns the largest integer not larger than x. ceiling
returns the smallest integer not smaller than x. truncate
returns the integer of maximal absolute value not larger than x.
round returns the closest integer to x, rounding to even when x
is halfway between two integers. With two arguments,
rationalize produces the best rational approximation to x within
the tolerance specified by y. With one argument, rationalize
produces the best rational approximation to x, preserving all of
the precision in its representation.
(exp z) procedure
(log z) procedure
(expt z1 z2) procedure
(sqrt z) procedure
(sin z) procedure
(cos z) procedure
(tan z) procedure
(asin z) procedure
(acos z) procedure
(atan z1 z2) procedure
These procedures are part of every implementation that supports
real numbers. Their meanings conform with the Common Lisp
standard. (Be careful of the branch cuts if complex numbers are
allowed.)
(make-rectangular x1 x2) procedure
(make-polar x3 x4) procedure
(real-part z) procedure
(imag-part z) procedure
(magnitude z) procedure
(angle z) procedure
These procedures are part of every implementation that supports
complex numbers. Suppose x1, x2, x3, and x4 are real numbers
and z is a complex number such that
z = x1 + x2 i = x3 * e ↑ (x4 i)
Then make-rectangular and make-polar return z, real-part returns
x1, imag-part returns x2, magnitude returns x3, and angle
returns x4.
(exact->inexact z) procedure
(inexact->exact z) procedure
exact->inexact returns an inexact representation of z, which is
a pretty harmless thing to do. inexact->exact returns an exact
representation of z; be sure you know what you are doing here!
!II.7. Numbers (part 2)
Numerical Input and Output.
Scheme allows all of the traditional ways of expressing
numerical constants, though any particular implementation may
support only some of them. These expressions are intended to be
purely notational; any kind of number may be expressed in any
form that the user deems convenient. Of course, expressing 1/7
as a limited-precision decimal fraction will not exactly express
the number, but this approximate expression may be just what the
user wants to see.
The expressions of numerical constants can be specified using
formats. The system provides a procedure, number->string, which
takes a number and a format and which produces a string which is
the printed expression of the given number in the given format.
(number->string number format) procedure
This procedure will mostly be used by sophisticated users and in
system programs. In general, a naive user will need to know
nothing about the formats because the system printer will have
reasonable default formats for all types of NUMBERs. The system
reader will construct reasonable default numerical types for
numbers expressed in each of the formats it recognizes. If a
user needs control of the coercion from strings to numbers he
will use string->number, which takes a string, an exactness, and
a radix and which produces a number of the maximally precise
applicable type expressed by the given string.
(string->number string exactness radix) procedure
The exactness is a symbol, either E (for EXACT) or I (for
INEXACT). The radix is also a symbol: B for binary, O for
octal, D for decimal, and X for hexadecimal. Returns a number
parsed from the string.
Formats may have parameters. For example, the (SCI 5 2) format
specifies that a number is to be expressed in Fortran scientific
format with 5 significant places and two places after the radix
point.
The following are all numerical constant expressions. The
comment shows the format that was used to produce the
expression:
123 +123 -123 ; (INT)
12345678901234567890123456789 ; A big one!
355/113 -355/113 +355/113 ; (RAT)
+123.45 -123.45 ; (FIX 2)
3.14159265358979 ; (FIX 14)
3.14159265358979 ; (FLO 15)
123.450 ; (FLO 6)
-123.45E-1 ; (SCI 5 2)
123E3 123E-3 -123E-3 ; (SCI 3 0)
-1+2i ; (RECT (INT) (INT))
1.2@1.570796 ; (POLAR (FIX 1) (FLO 7))
A numerical constant may be specified with an explicit radix by
a prefix. The prefixes are: #B (binary), #O (octal), #D
(decimal), #X (hex). A format may specify that a number be
expressed in a particular radix. The radix prefix may be
suppressed. For example, one may express a complex number in
polar form with the magnitude in octal and the angle in decimal
as follows:
#o1.2@#d1.570796327 ; (POLAR (FLO 2 (RADIX O)) (FLO (RADIX D)))
#o1.2@1.570796327 ; (POLAR (FLO 2 (RADIX O)) (FLO (RADIX D S))
A numerical constant may be specified to be either EXACT or
INEXACT by a prefix. The prefixes are: #I (inexact), #E
(exact). An exactness prefix may appear before or after any
radix prefix that is used. A format may specify that a number
be expressed with an explicit exactness prefix, or it may force
the exactness to be suppressed. For example, the following are
ways to output an inexact value for pi:
#I355/113 ; (RAT (EXACTNESS))
355/113 ; (RAT (EXACTNESS S))
#I3.1416 ; (FIX 4 (EXACTNESS))
An attempt to produce more digits than are available in the
internal machine representation of a number will be marked with
a "#" filling the extra digits. This is not a statement that
the implementation knows or keeps track of the significance of a
number, just that the machine will flag attempts to produce 20
digits of a number which has only 15 digits of machine
representation:
3.14158265358979##### ; (FLO 20 (EXACTNESS S))
In systems with both single and double precision FLONUMs one may
want to specify which size we want to use to internally
represent a constant. For example, we may want a constant that
is pi rounded to the single precision length, or we might want a
long number which has the value 6/10. In either case, we are
specifying an explicit way to represent an INEXACT number. For
this purpose, we allow one to express a number with a prefix
which indicates short or long FLONUM representation:
#S3.14159265358979 ; Round to short -- 3.141593
#L.6 ; Extend to long -- .600000000000000
Details of formats.
The format of a number is notated as a list beginning with a
format descriptor, such as SCI. Following the descriptor are
parameters used by that descriptor, such as the number of
significant digits to be used. Parameters which are omitted are
defaulted. Next, one may specify modifiers, such as RADIX or
EXACTNESS, which themselves may be parameterized. The format
descriptors are:
(INT)
Express as an integer. The radix point is implicit. If there are
not enough significant places, as in trying to express 6.0238E23
(internally represented as a 7 digit FLONUM) as an integer we would
get "6023800################".
(RAT n)
Express as a rational fraction. n specifies the largest
denominator to be used in constructing a rational approximation to
the number being expressed. If n is omitted it defaults to
infinity.
(FIX n)
Express with a fixed radix point. n specifies the number of
places to the right of the radix point. n defaults to the size of a
single-precision FLONUM. If there are not enough significant
places, as in trying to express 6.0238E23 (internally represented
as a 7 digit FLONUM) as a (FIX 2) we would get
"6023800################.##".
(FLO n)
Express with a floating radix point. n specifies the total number
of places to be displayed. n defaults to the size of a single-
precision FLONUM. If the number is out of range, it is converted
to (SCI). (FLO H) allows the system to heuristically express a FLO
for human consumption (as in the MacLisp printer).
(SCI n m)
Express in exponential notation. n specifies the total number of
places to be displayed. n defaults to the size of a single-
precision FLONUM. m specifies the number of places to the right of
the radix point. m defaults to n-1. (SCI H) does heuristic
expression.
(RECT r i)
Express as a rectangular form complex number. r and i are formats
for the real and imaginary parts respectively. They default to
∂19-Mar-85 0515 @MIT-MC:forwarder@CSNET-SH.ARPA Message a011267 LONG message - part 3
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 19 Mar 85 05:15:11 PST
Received: from CSNET-SH by MIT-MC.ARPA; 19 MAR 85 08:07:47 EST
To: scheme@MIT-MC.ARPA
Subject: Message a011267 LONG message - part 3
Reply-to: cic@CSNET-SH.ARPA
Date: 19 Mar 85 07:53:34 EST (Tue)
From: "Charlotte D. Mooers" <postmaster@CSNET-SH.ARPA>
(HEUR).
(POLAR m a)
Express as a polar form complex number. m and a are formats for
the magnitude and angle respectively. m and a default to (HEUR).
(HEUR)
Express heuristically, as in the MacLisp printer (see Steele),
using the minimum number of digits required to get an expression
which when coerced back to a number produces the original machine
representation. EXACT numbers are expressed as (INT) or (RAT).
INEXACT numbers are expressed as (FLO H) or (SCI H) depending on
their range. Complex numbers are expressed in (RECT). This is the
normal default of the system printer.
The following modifiers may be added to a numerical format
specification:
(EXACTNESS s)
This controls the expression of the exactness label of a number. s
indicates whether the exactness is to be E (expressed) or S
(suppressed). s defaults to E. If no exactness modifier is
specified for a format the exactness is by default not expressed.
(RADIX r s)
This forces a number to be expressed in the radix r. r may be B
(binary), O (octal), D (decimal), or X (hex). s indicates whether
the radix label is to be E (expressed) or S (suppressed). s
defaults to E. If no radix modifier is specified the default is
decimal and the label is suppressed.
! II.8. Strings
Strings are written as sequences of characters enclosed within
doublequotes ("). A doublequote can be written inside a string
only by escaping it with a backslash (\), as in
"The word \"Recursion\" has many different meanings."
A backslash can be written inside a string only by escaping it
with another backslash. Scheme does not specify the effect of a
backslash within a string that is not followed by either a
doublequote or another backslash.
A string may continue from one line to the next, but this is
usually a bad idea because the exact effect varies from one
computer system to another.
Several of the string procedures involve characters or lists of
characters. Characters are written using the #\ notation of
Common Lisp. For example:
#a ; lower case letter
#A ; upper case letter
#( ; the left parenthesis as a character
# ; the space character
#space ; the preferred way to notate a space character
#newline ; the newline character
The #\ notation is not an essential part of Scheme, however.
Even implementations that support the #\ notation for input do
not have to support it for output, and there is no requirement
that the data type of characters be disjoint from data types
such as integers or strings.
This section defines no destructive operations on strings, but a
much larger collection of string operations including
destructive operations has been proposed by Chris Hanson and is
under consideration.
(string? obj) essential procedure
Returns #!true if obj is a string, otherwise returns #!false.
(string-equal? string1 string2) essential procedure
Returns #!true if string1 and string2 are strings of the same
length and have the same characters in the same positions.
(string-less? string1 string2) essential procedure
Returns #!true if string1 is lexicographically less than
string2. The ordering defined by string-less? varies from one
computer system to another, but it is always an irreflexive
total ordering on strings.
(string-length string) essential procedure
Returns the number of characters in string.
(string-ref string k) essential procedure
k must be a nonnegative integer less than the string-length of
string. Returns character k of string using zero-origin
addressing.
(string-ref "abcde" 2) --> #c
(string-append string1 string2) essential procedure
(string-append string ...) procedure
Returns a string whose characters form the catenation of the
given strings.
(string->list string) essential procedure
Returns a list of the characters that make up string. See
list->string.
(list->string char-list) essential procedure
char-list must be a proper list of characters. Returns a string
formed from the characters in char-list. list->string and
string->list are inverses so far as equal? is concerned.
!II.9. Vectors
Vectors are heterogenous mutable structures whose elements are
indexed by integers. The first element in a vector is indexed
by zero, and the last element is indexed by one less than the
length of the vector. A vector of length 3 containing the
number 0 in element 0, the list (2 2 2 2) in element 1, and the
string "Anna" in element 2 can be written as
#(0 (2 2 2 2) "Anna")
Vectors are created by the constructor procedure make-vector.
The elements are accessed and assigned by the procedures
vector-ref and vector-set!.
(vector? obj) essential procedure
Returns #!true if obj is a vector, otherwise returns #!false.
(make-vector size) essential procedure
(make-vector size fill) procedure
Returns a newly allocated vector of size elements. If a second
argument is given, then each element is initialized to fill.
Otherwise the initial contents of each element is unspecified.
(vector obj ...) essential procedure
Returns a newly allocated vector whose elements contain the
given arguments. Analogous to list.
(vector 'a 'b 'c) --> #(a b c)
(vector-length vec) essential procedure
Returns the number of elements in the vector vec.
(vector-ref vec k) essential procedure
Returns the contents of element k of the vector vec. k must be
a nonnegative integer less than the vector-length of vec.
(vector-ref '#(1 1 2 3 5 8 13 21) 5) --> 8
(vector-set! vec k obj) essential procedure
Stores obj in element k of the vector vec. k must be a
nonnegative integer less than the vector-length of vec. The
value returned by vector-set! is not specified.
(define vec '#(0 (2 2 2 2) "Anna")) --> vec
(vector-set! vec 1 '("Sue" "Sue")) --> unspecified
vec --> #(0
("Sue" "Sue")
"Anna")
(vector->list vec) essential procedure
Returns a list of the objects contained in the elements of vec.
See list->vector.
(vector->list '#(dah dah didah)) --> (dah dah didah)
(list->vector elts) essential procedure
Returns a newly created vector whose elements are initialized to
the elements of the proper list elts.
(list->vector '(dididit dah)) --> #(dididit dah)
(vector-fill! vec fill) procedure
Stores fill in every element of the vector vec. The value
returned by vector-fill! is not specified.
!II.10. The object table
(object-hash obj) procedure
(object-unhash n) procedure
object-hash associates an integer with obj in a global table and
returns obj. object-hash guarantees that distinct objects (in
the sense of eq?) are associated with distinct integers.
object-unhash takes an integer and returns the object associated
with that integer if there is one, returning false otherwise.
Rationale: object-hash and object-unhash can be implemented
using association lists and the assq procedure, but the intent
is that they be efficient hash functions for general objects.
!II.11. Procedures
Procedures are created when lambda expressions are evaluated.
Procedures do not have a standard printed representation because
recursively defined procedures are conceptually infinite and may
be implementationally circular.
The most common thing to do with a procedure is to call it with
zero or more arguments. A Scheme procedure may also be stored
in data structures or passed as an argument to procedures such
as those described below.
(apply proc args) essential procedure
(apply proc arg1 ... args) procedure
proc must be a procedure and args must be a proper list of
arguments. The first (essential) form calls proc with the
elements of args as the actual arguments. The second form is a
generalization of the first that calls proc with the elements of
(append (list arg1 ...) args) as the actual arguments.
(apply + (list 3 4)) --> 7
(define compose
(lambda (f g)
(lambda args
(f (apply g args))))) --> compose
((compose 1+ *) 3 4) --> 13
(mapcar f plist) essential procedure
(mapcar f plist1 plist2 ...) procedure
f must be a procedure of one argument and the plists must be
proper lists. If more than one plist is given, then the plists
should all be the same length. Applies f element-wise to the
elements of the plists and returns a list of the results. The
order in which f is applied to the elements of the plists is not
specified.
(mapcar cadr '((a b) (d e) (g h))) --> (b e h)
(mapcar (lambda (n) (expt n n))
'(1 2 3 4 5)) --> (1 4 27 256 3125)
(mapcar + '(1 2 3) '(4 5 6)) --> (5 7 9)
(define count 0) --> unspecified
(mapcar (lambda (ignored)
(set! count (1+ count))
count)
'(a b c)) --> unspecified
The mapcar procedure often goes by the name of map in other
advanced programming languages.
(mapc f plist) essential procedure
(mapc f plist1 plist2 ...) procedure
The arguments to mapc are like the arguments to mapcar, but mapc
calls f for its side effects rather than for its values. Unlike
mapcar, mapc is guaranteed to call f on the elements of the
plists in order from the first element to the last, and the
value returned by mapc is not specified.
(define v (make-vector 5)) --> v
(mapc (lambda (i)
(vector-set! v i (* i i)))
'(0 1 2 3 4)) --> unspecified
v --> #(0 1 4 9 16)
The name of mapc is traditional and cannot otherwise be
defended.
(call-with-current-continuation f) procedure
The classic use of call-with-current-continuation is for
structured, non-local exits from loops or procedure bodies, but
in fact call-with-current-continuation is extremely useful for
implementing a wide variety of advanced control structures.
Whenever a Scheme expression is evaluated there is a
continuation wanting the result of the expression. The
continuation represents an entire future for the computation.
If the expression is evaluated at top level, for example, then
the continuation will take the result, print it on the screen,
prompt for the next input, evaluate it, and so on forever. Most
of the time the continuation includes actions specified by user
code, as in a continuation that will take the result, multiply
it by the value stored in a local variable, add seven, and give
the answer to the top level continuation to be printed.
Normally these ubiquitous continuations are hidden behind the
scenes and programmers don't think much about them. On rare
occasions, however, when programmers need to do something fancy,
then they may need to deal with continuations explicitly.
call-with-current-continuation allows Scheme programmers to
create a procedure that acts just like the current continuation.
f must be a procedure of one argument.
call-with-current-continuation packages up the current
continuation as an "escape procedure" and passes it as an
argument to f. The escape procedure is an ordinary Scheme
procedure of one argument that, if it is later passed a value,
will ignore whatever continuation is in effect at that later
time and will give the value instead to the continuation that
was in effect when the escape procedure was created.
The escape procedure created by call-with-current-continuation
has unlimited extent just like any other procedure in Scheme.
It may be stored in variables or data structures and may be
called as many times as desired.
The following examples show only the most common uses of
call-with-current-continuation. If all real programs were as
simple as these examples, there would be no need for a procedure
with the power of call-with-current-continuation.
(call-with-current-continuation
(lambda (exit)
(mapc (lambda (x)
(if (negative? x)
(exit x)))
'(54 0 37 -3 245 19))
#!true)) --> -3
(define list-length
(lambda (obj)
(call-with-current-continuation
(lambda (return)
((rec loop (lambda (obj)
(cond ((null? obj) 0)
((pair? obj)
(1+ (loop (cdr obj))))
(else (return #!false)))))
obj)))))
--> list-length
(list-length '(1 2 3 4)) --> 4
(list-length '(a b . c)) --> #!false
Rationale: Most serious programming languages incorporate one or
more special purpose escape constructs with names like exit,
return, or even goto. In 1965, however, Peter Landin invented a
general purpose escape operator called the J-operator. John
Reynolds described a simpler but equally powerful construct in
1972. The catch special form described by Sussman and Steele in
the 1975 report on Scheme is exactly the same as Reynolds's
construct, though its name came from a less general construct in
MacLisp. The fact that the full power of Scheme's catch could
be obtained using a procedure rather than a special form was
noticed in 1982 by the implementors of Scheme 311, and the name
call-with-current-continuation was coined later that year. Some
people think the name is good because its length discourages
programmers from using the procedure casually; others have taken
to calling the procedure call/cc.
!II.12. Ports
Ports represent input and output devices. To Scheme, an input
device is a Scheme object that can deliver characters upon
command, while an output device is a Scheme object that can
accept characters.
(call-with-input-file string proc) essential procedure
(call-with-output-file string proc) essential procedure
proc is a procedure of one argument, and string is a string
naming a file. For call-with-input-file, the file must already
exist; for call-with-output-file, the effect is unspecified if
the file already exists. Calls proc with one argument: the port
obtained by opening the named file for input or output. If the
file cannot be opened, an error is signalled. If the procedure
returns, then the port is closed automatically and the value
yielded by the procedure is returned. If the current
continuation ever changes in such a way as to make it doubtful
that the procedure will return, the port may be closed
automatically, but the exact interaction with escape procedures
is unspecified.
Rationale: Whether or not the port is closed when the procedure
does not return is mainly a performance issue, of greatest
importance when there is a small limit on the number of files
that can be open at once. The extreme generality of Scheme's
escape procedures makes it impossible to know for certain
whether a procedure will return, and procedures can in fact
return more than once.
(input-port? obj) essential procedure
(output-port? obj) essential procedure
Returns #!true if obj is an input port or output port
(respectively), otherwise returns #!false.
(current-input-port) essential procedure
(current-output-port) essential procedure
Returns the current default input or output port.
(with-input-from-file string thunk) procedure
(with-output-to-file string thunk) procedure
thunk is a procedure of no arguments, and string is a string
naming a file. For with-input-from-file, the file must already
exist; for with-output-to-file, the effect is unspecified if the
file already exists. The file is opened for input or output, an
input or output port connected to it is made the default value
returned by current-input-port or current-output-port, and the
thunk is called with no arguments. When the thunk returns, the
port is closed and the previous default is restored.
with-input-from-file and with-output-to-file return the value
yielded by thunk. Furthermore these procedures will attempt to
close the default port and restore the previous default whenever
the current continuation changes in such a way as to make it
doubtful that the thunk will ever return. See
call-with-input-file and call-with-output-file.
(open-input-file filename) procedure
Takes a string naming an existing file and returns an input port
capable of delivering characters from the file. If the file
cannot be opened, an error is signalled.
(open-output-file filename) procedure
Takes a string naming an output file to be created and returns
an output port capable of writing characters to a new file by
that name. If the file cannot be opened, an error is signalled.
If a file with the given name already exists, the effect is
unspecified.
(close-input-port port) procedure
(close-output-port port) procedure
Closes the file associated with port, rendering the port
incapable of delivering or writing characters. The value
returned is not specified.
!II.13. Input
The read procedure converts written representations of Scheme
objects into the objects themselves. The written
representations for Scheme objects are described in the sections
devoted to the operations on those objects, and the grubby
details of lexical syntax are described in an appendix.
(eof? obj) essential procedure
Returns true iff obj is an end of file object. The precise set
of end of file objects will vary among implementations, but in
any case no end of file objects will ever be a character or an
object that can be read in using read.
(read) essential procedure
(read port) essential procedure
Returns the next object parsable from the given input port,
updating port to point to the first character past the end of
the written representation of the object. If an end of file is
encountered in the input before any characters are found that
can begin an object, then an end of file object is returned. If
an end of file is encountered after the beginning of an object's
written representation, but the written representation is
incomplete and therefore not parsable, an error is signalled.
The port argument may be omitted, in which case it defaults to
the value returned by current-input-port.
Rationale: This corresponds to Common Lisp's
read-preserving-whitespace, but for simplicity it is never an
error to encounter end of file except in the middle of an
object.
(read-char) essential procedure
(read-char port) essential procedure
Reads the next character available from the input port, updating
the port to point to the following character. If no more
characters are available, an end of file object is returned.
port may be omitted, in which case it defaults to the value
returned by current-input-port.
(listen?) procedure
(listen? port) procedure
Returns true if a character is ready on the input port so that a
read-char operation will not hang, and returns false otherwise.
If the port is at end of file then the value returned by listen?
is unspecified. port may be omitted, in which case it defaults
to the value returned by current-input-port.
(load filename) essential procedure
filename should be a string naming an existing file containing
Scheme source code. The load procedure reads expressions from
the file and evaluates them sequentially as though they had been
typed interactively. It is not specified whether the results of
the expressions are printed, however, nor is it specified
whether the load procedure affects the values returned by
current-input-stream and current-output-stream during the
loading process. load returns an unspecified value.
Rationale: For portability load must operate on source files.
Its operation on other kinds of files necessarily varies among
implementations.
!II.14. Output
(write obj) essential procedure
(write obj port) essential procedure
Writes a representation of obj to the given port. Strings that
appear in the written representation are enclosed in
doublequotes, and within those strings backslash and doublequote
characters are escaped by backslashes. write returns an
unspecified value. The port argument may be omitted, in which
case it defaults to the value returned by current-output-stream.
See display.
(display obj) essential procedure
(display obj port) essential procedure
Writes a representation of obj to the given port. Strings that
appear in the written representation are not enclosed in
doublequotes, and no characters are escaped within those
strings. display returns an unspecified value. The port
argument may be omitted, in which case it defaults to the value
returned by current-output-stream. See write.
Rationale: Like Common Lisp's prin1 and princ, write is for
producing machine-readable output and display is for producing
human-readable output. Implementations that allow
"slashification" within symbols will probably want write but not
display to slashify funny characters in symbols.
(newline) essential procedure
(newline port) essential procedure
Writes an end of line to port. Exactly how this is done differs
from one operating system to another. Returns an unspecified
value. The port argument may be omitted, in which case it
defaults to the value returned by current-output-port.
(write-char char) essential procedure
(write-char char port) essential procedure
Writes the character char (not a written representation of the
character) to the given port and returns an unspecified value.
The port argument may be omitted, in which case it defaults to
the value returned by current-output-port.
(transcript-on filename) procedure
(transcript-off) procedure
filename must be a string naming an output file to be created.
The effect of transcript-on is to open the named file for
output, and to cause a transcript of subsequent interaction
between the user and the Scheme system to be written to the
file. The transcript is ended by a call to transcript-off,
which closes the transcript file. Only one transcript may be in
progress at any time, though some implementations may relax this
restriction. The values returned by these procedures are
unspecified.
Rationale: These procedures are redundant in some systems, but
systems that need them should provide them.
!References
Harold Abelson and Gerald Jay Sussman with Julie Sussman,
Structure and Interpretation of Computer Programs, MIT Press,
1985.
William Clinger, "The Scheme 311 compiler: an exercise in
denotational semantics", Conference Record of the 1984 ACM
Symposium on Lisp and Functional Programming, August 1984, pages
356-364.
Carol Fessenden, William Clinger, Daniel P Friedman, and
Christopher Haynes, "Scheme 311 version 4 reference manual",
Indiana University Computer Science Technical Report 137,
February 1983.
D Friedman, C Haynes, E Kohlbecker, and M Wand, "Scheme 84
interim reference manual", Indiana University Computer Science
Technical Report 153, January 1985.
Christopher T Haynes, Daniel P Friedman, and Mitchell Wand,
"Continuations and coroutines", Conference Record of the 1984
ACM Symposium on Lisp and Functional Programming, August 1984,
pages 293-298.
Peter Landin, "A correspondence between Algol 60 and Church's
lambda notation: Part I", Communications of the ACM 8, 2,
February 1965, pages 89-101.
MIT Scheme Manual, Seventh Edition, September 1984.
Peter Naur et al, "Revised report on the algorithmic language
Algol 60", Communications of the ACM 6, January 1963, pages
1-17.
Kent M Pitman, The Revised MacLisp Manual, MIT Artificial
Intelligence Laboratory Technical Report 295, 21 May 1983
(Saturday Evening Edition).
Jonathan A Rees, Norman I Adams, James R Meehan, "The T manual",
Fourth Edition, 10 January 1984.
John Reynolds, "Definitional interpreters for higher order
programming languages", ACM Conference Proceedings, 1972, pages
717-740.
Guy Lewis Steele Jr and Gerald Jay Sussman, "The revised report
on Scheme, a dialect of Lisp", MIT Artificial Intelligence
Laboratory Memo 452, January 1978.
Guy L Steele, Rabbit: a compiler for Scheme, MIT Artificial
Intelligence Laboratory Technical Report 474, May 1978.
Guy L Steele, "An overview of Common Lisp", Conference Record of
the 1982 ACM Symposium on Lisp and Functional Programming,
August 1982, pages 98-107.
Guy Lewis Steele Jr, Common Lisp: the Language, Digital Press,
1984.
Gerald Jay Sussman and Guy Lewis Steele Jr, "Scheme: an
interpreter for extended lambda calculus", MIT Artificial
Intelligence Laboratory Memo 349, December 1975.
Gerald Jay Sussman, Jack Holloway, Guy L Steele, and Alan Bell,
"Scheme-79 -- Lisp on a chip", IEEE Computer 14, 7, July 1981,
pages 10-21.
∂19-Mar-85 1044 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa Keyboard inputs
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 19 Mar 85 10:44:39 PST
Received: from csnet-relay by MIT-MC.ARPA; 19 MAR 85 13:43:27 EST
Received: from indiana by csnet-relay.csnet id a008437; 19 Mar 85 13:42 EST
Date: Tue, 19 Mar 85 10:55:58 est
From: Will Clinger <willc%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA03087; Tue, 19 Mar 85 10:55:58 est
To: scheme@mit-mc.ARPA
Subject: Keyboard inputs
> On interactive streams users may have the possibility of
>erasing typed characters. What happens if listen? returns true and
>then the user erases the character? The program which invoked listen?
>will probably attempt to read a character thinking that it will not
>hang but it will. We had this bug and went to a fair amount of hair
>to get it fixed.
This problem doesn't arise if the rubout handler is implemented
using READ-CHAR. The system should be designed this way if you
expect to implement an Emacs-like editor in Scheme.
If the rubout handler is at a lower level than READ-CHAR, then
the system is probably set up so that the user first edits her
input using rubouts and whatever other facilities are available
(cut and paste using a mouse, Emacs, whatever). Let's say that
this input is liquid. When the user is satisfied with her input
she does something to signal that the input should be sent to
Scheme, perhaps by typing the "Execute" key (on the HP 9836) or
the "Enter" key (on the Macintosh). At that moment the input
should be frozen so that it cannot be edited further. At any
given time the input buffer for READ-CHAR may contain older
characters that are frozen as well as newer characters that are
liquid. READ-CHAR should return only frozen characters, and
should hang if there are none. The LISTEN? procedure (or whatever
we wind up calling it) should therefore return true only if there
are frozen characters in the buffer.
It is possible to design a system that can switch back and forth
between the first way and the second way. (Unix calls these raw
mode and cooked mode.)
> We have not talked at all about keyboard interrupts. It
>seems to me that any reasonable implementation should provide a
>way for the user to (at least) abort an infinite loop. It would
>be nice if we had a simple standard mechanism for doing this, but
>implementations would be free to have more keyborad interrupts
>(we currently have 5 by default). I propose that we choose some
>control character (↑G, for example) which on all implementations
>and unless inhibited (an editor may want to do this) will
>interrupt Scheme and make it return to the top-level
>read-eval-print loop.
Yes, any reasonable implementation must have keyboard interrupts,
but we shouldn't standardize on the characters. Consider Scheme
312, which runs under four very different operating systems.
Under CP/M-68k, control-G is fine as the interrupt character, and
an operating system convention leads users to expect that
control-C will leave Scheme for good (it does). Under Un*x,
however, users expect SIGINT to be the interrupt character and
SIGQUIT to be the abort character; usually these are control-C
and control-\, respectively. Under HP Pascal the HP 9836
"Execute" key is rigged to send a control-C; it doesn't make
sense for "Execute" to interrupt or abort. The Macintosh doesn't
have a control key (the command (cloverleaf) key is something
completely different); pull-down menus are probably more
appropriate. In short, no matter what conventions we could
choose, they would be wrong for some machines.
∂19-Mar-85 1445 @MIT-MC:JINX@MIT-OZ Keyboard inputs
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 19 Mar 85 14:45:37 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 19 MAR 85 17:44:34 EST
Date: 19 Mar 1985 17:44 EST (Tue)
Message-ID: <JINX.12096359061.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Will Clinger <willc%indiana.csnet@CSNET-RELAY.ARPA>
Cc: scheme@MIT-MC.ARPA
Subject: Keyboard inputs
In-reply-to: Msg of 19 Mar 1985 10:55-EST from Will Clinger <willc%indiana.csnet at csnet-relay.arpa>
I think you don't understand the problem with listen?
The system need not have a rubout handler written in Scheme to
have an Emacs-like editor. MIT-Scheme has a rubout handler written in
Pascal (almost all IO is written in Pascal), and Edwin (Chris Hanson's
editor) works perfectly fine, since it bypasses buffered IO.
We have two kinds of terminal read-char: One is used by the
reader, and is buffered (no characters are given to Scheme until some
key (Execute on HP9836, Newline on UNIX) is typed). The other is
immediate (it returns as soon as a character is typed, without waiting
for any special character). The former is much more efficient under
some operating systems, and eliminates the need for a complicated
rubout handler since the reader never needs to back out (according to
GJS, 1/4 of all the code of MacLisp at some point was the rubout
handler). Having an Emacs-like front-end is not incompatible with
this, since the front-end need not give any characters to Scheme until
no further character-level processing is needed.
It is inconvenient, however, to do all input in this mode (I'd
hate to have to type a newline after a single character command to a
debugger, for example). This is why we have immediate read-char also,
which is the default. Users can type asynchronously, and frequently
do so ahead of the system. For consistency, the user should be able
to edit (especially rub-out) his typeahead until it is read. Since
the system does not know whether the next read-char will be immediate
or not, it cannot lock the required characters unless it locks all,
clearly unpalatable.
The problem with listen? arises, for example, from programs
which ask for confirmation or a simple choice but assume a default if
no input becomes available in some period of time. Assume that the
user types a character, the program invokes listen? which returns
true, and the user then deletes the character before the program has
had a chance to invoke immediate read-char. This is quite likely on a
timesharing system, where the user may delete while Scheme is not the
current process running. Clearly the program will hang while it
should not (it was intended that it "time-out"). Clearly listen? is
wothless unless it applies to both liquid and frozen characters
(otherwise a terminator would have to be typed after the option,
ugh!). The problem is trivially solved if listen? locks the
character.
I believe that this problem can arise even if there is no
buffered io in a system. On Lisp systems that I know (including
MacLisp and Lisp Machines), rubout-handling is built into read, not
into tyi, and therefore user programs that use tyi rather than read do
not (by default) allow users to rub-out their input. If you allow
rub-out on read-char throughout the system (which is certainly
desirable), the problem potentially exists.
Since adding this extra constraint to the definition of
listen? solves all these bugs and allows implementors of the
io system greater freedom, I think it should be added.
On my previous message I advocated for eliminating listen? in
favor of non-hanging-read-char, but I drop this. Chris Hanson has
pointed out that unless untyi were provided, this would be the cause
of pretty ugly code.
∂19-Mar-85 2228 @MIT-MC:CPH@MIT-OZ Revisions to String Proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 19 Mar 85 22:28:35 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 20 MAR 85 01:24:39 EST
Date: Wed, 20 Mar 1985 01:24 EST
Message-ID: <CPH.12096442797.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: Scheme@MIT-MC
Subject: Revisions to String Proposal
I have revised the earlier proposal I submitted for String operations.
The revision was somewhat of a hatchet job, but I think that the
important functionality remains.
What follows is some notes referring to the earlier proposal. After
that I have written a small bit of commentary about mutation of
strings.
!
----------------------------------------------------------------------
Characters
The basic operations on characters are the following; they should be
essential.
(CHAR? <object>)
True iff <object> is a character.
(CHAR->INTEGER <char>)
(INTEGER->CHAR <integer>)
Maps to coerce characters to integers and vice versa. If two
characters have a certain relationship in the character ordering,
then the corresponding integers must have the same relationship in
the integer ordering. (If I recall right, this means these maps
are order isomorphisms between characters and integers.)
I would like to propose that the following be essential. These are
the case sensitive order predicates for characters; they define the
character ordering. I think that the Common Lisp restrictions as to
the ordering should be adopted.
The names have been changed to conform with Common Lisp, after Don
Oxley pointed out that CHAR-EQUAL? was case sensitive, and in CL
CHAR-EQUAL was the case insensitive version. I hope that this will
clear things up a bit.
Each of the following accepts two character objects, and compares them
in the obvious way. Optionally, they may take more arguments, as do
the corresponding numeric predicates.
CHAR=? CHAR<? CHAR<=? CHAR>? CHAR>=?
The following should be optional; they are the case insensitive
versions of the above.
CHAR-CI=? CHAR-CI<? CHAR-CI<=? CHAR-CI>? CHAR-CI>=?
These character class predicates should be optional, with the meaning
described in the Common Lisp manual. They each take one argument,
which must be a character.
CHAR-UPPER-CASE?
CHAR-LOWER-CASE?
CHAR-ALPHABETIC?
CHAR-NUMERIC?
CHAR-ALPHANUMERIC?
CHAR-WHITESPACE?
CHAR-GRAPHIC?
The following should be optional; each takes a character object and
returns another character object. They perform case conversion if the
argument is lower or upper case, respectively.
CHAR-UPCASE
CHAR-DOWNCASE
!
----------------------------------------------------------------------
Strings
I think that the following should be essential, as described in my
earlier proposal:
STRING? MAKE-STRING STRING-LENGTH STRING-REF STRING->LIST
LIST->STRING SUBSTRING STRING-APPEND STRING-NULL?
Similarly to the transformation for characters, the following should
be essential for two arguments, and optionally should take more.
STRING=? STRING<? STRING<=? STRING>? STRING>=?
Again, these case insensitive versions are optional.
STRING-CI=? STRING-CI<? STRING-CI<=? STRING-CI>? STRING-CI>=?
Next, these optional procedures provide a small set of operations for
mutable strings.
STRING-ALLOCATE STRING-COPY STRING-SET! SUBSTRING-FILL!
SUBSTRING-MOVE-RIGHT! SUBSTRING-MOVE-LEFT!
The remaining operations, while useful, are probably not important
enough to standardize on. As I have already demonstrated, all of them
can be implemented given the above operations.
Here is the corrected text for the -MOVE- operations:
(SUBSTRING-MOVE-RIGHT! STRING1 START1 END1 STRING2 START2)
(SUBSTRING-MOVE-LEFT! STRING1 START1 END1 STRING2 START2)
These operations destructively copy the substring <STRING1, START1,
END1> to the string STRING2 starting at the index START2. It must be
the case that <STRING2, START2, (+ START2 (- END1 START1))> is a
substring; this latter substring is destructively modified to contain
the contents of the former substring.
The operations differ only when the two substrings overlap, i.e. when
STRING1 and STRING2 are EQ? and the index sets of the substrings are
not disjoint. In this case, the operations are defined to copy the
elements of the first substring serially. SUBSTRING-MOVE-RIGHT!
copies the first substring starting with the rightmost element,
proceeding to the left, while SUBSTRING-MOVE-LEFT! starts with the
leftmost element, proceeding to the right. This has the effect that
the two operations can be used to shift groups of characters right or
left, respectively, within a given string.
!
----------------------------------------------------------------------
Mutation
I have tried to be careful about the issue of mutable strings. None
of the operations which I have proposed as "essential" mutate strings.
I have provided a small set of operations, marked as "optional", which
DO mutate strings. I believe that mutation of strings is basically
reasonable; although I understand that in some very important cases,
in particular the names of interned symbols, there should be some
guarantee that a string cannot be mutated. I believe that this can be
solved by one of these simple methods:
1. A string could have an internal bit which, when set, would prevent
mutation.
2. There could be two types of strings. In this case, it would be
reasonable to decide that the read/print syntax for mutable strings
need not be the same as for non-mutable strings.
Anyway, I have chosen to have all strings be mutable in the MIT
implementation, because that is the simplest choice providing the most
power. To the best of my knowledge, no one has ever been screwed by
this decision, and it seems unlikely that anyone ever would.
∂20-Mar-85 1254 JAR@MIT-MC Ports and streams
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 20 Mar 85 12:54:44 PST
Date: 20 March 1985 15:54-EST
From: Jonathan A Rees <JAR @ MIT-MC>
Subject: Ports and streams
To: SCHEME @ MIT-MC
I think that we generally agree that were it not for performance
reasons, we would have only streams (in the FP/A&S sense), and not
ports; am I correct? E.g., a stream object would need to be consed for
each character read from or written to a file; this would mean frequent
GC's if a lot of file I/O was happening. It's unfortunate that our
design is driven by considerations like this, but I guess that's how
things are.
So the I/O primitives in the essential dialect manipulate things called
ports, which are positions on streams of characters. The two notions
are equivalent (ports could be defined if the only primitives were stream
primitives, and vice versa), so people who care about writing code
which does I/O in a pure style can still do so, by implementing
I/O streams in terms of I/O ports themselves.
So far so good. This message is about terminology, not semantics. I
think that "port" is a bad term. The real-life usage of the term "port"
(door or harbor) doesn't seem to be a good fit with that of the word
"stream". I guess the image that's intended is of a door, with the
program on one side and a stream of things on the other, and the things
coming into the program's awareness or control through the door. Or
perhaps the stream flows through the door? Streams flow under bridges,
maybe, or through channels (I don't like "channel" because it has
incompatible connotations in computer science), or into aqueducts or
over waterfalls, but through doors? The other meaning of "port"
doesn't make sense: rivers or possibly streams might flow into harbors
or ports, but that's not what makes a port a port; a port is someplace
where ships dock, load, etc. So "port" is a very strange word to use in
connection with streams.
A different metaphor is that a "port" is a sort of a cursor or a marker
which moves along a sequence (stream). Well, what moves up and down a
sequence or stream? Here are some transportation metaphors:
line, screen cursor
conduit vehicle
rail train
road car
river boat
stream raft
How about "raft"? A raft might be an appropriate vehicle for a stream.
I guess this is pretty cutesy, but it's an idea. One argument in favor
is that "raft" doesn't have connotations in computer science like many
other words (port, channel) do. Also, the metaphor is obscure enough
that no one would need to know how silly it is; users could imagine that
RAFT is an acronym, or some technical term derived from some obscure
branch of mathematics or semantics, or whatever. Sounds sort of like
"rack" or "rail," terms that certain language designers use without
embarrassment. And it's short, a distinct advantage.
These two metaphors reflect the difference between a stream and a
streambed. If you want to see everything which floats by on a stream,
it's sufficient to sit one place (e.g. on a bridge, or on a bank, or at
its outlet) and relax and enjoy the view. "Stream" here is the stuff
that is flowing. If, however, you want to see all the places that the
stream goes, you have to get on a raft or boat or just wade the entire
length of the thing from source to outlet. This "stream" is a
geographical thing, something you'd find on a map.
Besides the fact that "port" is a mixed (or at least poor) metaphor, I
am opposed to the term because it reminds me of Franz Lisp. I'd rather
not be reminded of Franz every time I use Scheme.
I know this is pretty random, but I just wanted to voice my unhappiness
and get people thinking about more appropriate terms.
Jonathan
∂20-Mar-85 1542 @MIT-MC:KMP@SCRC-STONY-BROOK Ports and streams
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 20 Mar 85 15:42:09 PST
Received: from SCRC-STONY-BROOK by MIT-MC via Chaosnet; 20 MAR 85 18:36:30 EST
Received: from SCRC-RIO-DE-JANEIRO by SCRC-STONY-BROOK via CHAOS with CHAOS-MAIL id 200687; Wed 20-Mar-85 17:11:04-EST
Date: Wed, 20 Mar 85 17:11 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: Ports and streams
To: Scheme@MIT-MC.ARPA
cc: JAR@MIT-MC.ARPA
In-Reply-To: The message of 20 Mar 85 15:54-EST from Jonathan A Rees <JAR at MIT-MC>
Message-ID: <850320171127.2.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Date: 20 March 1985 15:54-EST
From: Jonathan A Rees <JAR @ MIT-MC>
... A different metaphor is that a "port" is a sort of a cursor or a
marker which moves along a sequence (stream). Well, what moves up
and down a sequence or stream? How about "raft"? ...
I also dislike "port" for much the same reasons as Jonathan presented.
I support the proposal for the new term "raft".
∂21-Mar-85 1448 @MIT-MC:linus!ramsdell@mitre-bedford MAPC and MAPCAR
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Mar 85 14:46:23 PST
Received: from mitre-bedford by MIT-MC.ARPA; 21 MAR 85 17:46:38 EST
Date: 21 Mar 1985 17:35:15-EST
From: linus!ramsdell@Mitre-Bedford
Received: by linus.UUCP (4.12/4.7)
id AA18613; Thu, 21 Mar 85 09:30:14 est
Date: Thu, 21 Mar 85 09:30:14 est
From: linus!ramsdell (John D. Ramsdell)
Message-Id: <8503211430.AA18613@linus.UUCP>
To: bccvax!scheme@mit-mc.arpa
Subject: MAPC and MAPCAR
I mildly support the change from "port" to "raft", but
GREATLY support changes in other SCHEME names. In particular,
I find the terms MAPC and MAPCAR offensive. Why not use the
names WALK and MAP as is done in T?
I like the idea of using english words as names. Thus I prefer
LABELS to LETREC. Given that some names will not be english,
at the very least, word parts can be separated with dash.
LETREC => LET-REC
DEFREC => DEF-REC
NEWLINE => NEW-LINE
As you can guess, CAR and CDR are losers in my book. How about:
CAR => -<-
CDR => ->-
CADR => -<>-
CDAR => -><-
CxxxR => -xxx- with "A" substituted by "<" and "D" substituted by ">".
Bold and wonderful changes from traditional Lisps are being suggested by
the Scheme document, for example, dumping the confusion between the
empty list and logical false. Now is no time to get stuck with
traditional name.
John
∂21-Mar-85 1449 @MIT-MC:linus!ramsdell@mitre-bedford Re: DRAFT of the Revised Revised Report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Mar 85 14:48:42 PST
Received: from mitre-bedford by MIT-MC.ARPA; 21 MAR 85 17:47:31 EST
Date: 21 Mar 1985 17:35:34-EST
From: linus!ramsdell@Mitre-Bedford
Received: by linus.UUCP (4.12/4.7)
id AA21592; Thu, 21 Mar 85 13:35:25 est
Date: Thu, 21 Mar 85 13:35:25 est
From: linus!ramsdell (John D. Ramsdell)
Message-Id: <8503211835.AA21592@linus.UUCP>
To: bccvax!scheme@mit-mc.arpa
Subject: Re: DRAFT of the Revised Revised Report
A few comments:
1) How about consolidating descriptions of all procedures
that convert things to a string. E.g. symbol->string
should be described in the same section as number->string.
Part II: A catalog of Scheme
II.5 Symbols
II.6 Numbers
II.7 Vectors
II.8 Strings
II.9 String conversions. <-!
II.10 The object table
II.11 Procedures
II.12 Ports
II.13 Input
II.14 Output
2) When I use a one arm if, I am usually writting side effects,
but with a two arm if, I am not. I suggest these two different
uses be glorified with different names. In particular, let's
name the one arm if "when".
(if condition consequent alternative) essential special form
(when condition expr1 expr2 ...) essential special form
The result of the when is undefined.
3) Since define has two syntaxes, how about giving rec or
named-lambda the same two. You could drop one of the
special forms as a result.
(named-lambda (name var1 ...) expr ...) special form
(named-lambda name expr ...) special form
4) I think it is great that the value of set! is undefined.
5) What happened to iterate? I use it much more than I use do.
It would be nice to name it loop, but I'm sure the T people would
object.
6) Macro not defined in the begining of the report.
v
`pattern macro special form
7) It is excellent that there is an attempt to stop confusing
the empty list with boolean false.
8) The phrase "more inclined to..." does not sound like the kind
of words one should use in a description of eqv?.
be used to compare numbers. The eqv? procedure is just like eq?
except that it is more inclined to say that two numbers are the
same.
9) Missing predicate: list?.
(list? obj) essential procedure
(define (list? l) (or (pair? l) (null? l)))
10) I was happy to find that property lists are not part of the
definition of symbols.
11) I vote for the long name instead of call/cc.
(call-with-current-continuation f) procedure
John
∂21-Mar-85 1554 @MIT-MC:JINX@MIT-OZ DRAFT of the Revised Revised Report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Mar 85 15:51:13 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 21 MAR 85 18:51:21 EST
Date: 21 Mar 1985 18:49 EST (Thu)
Message-ID: <JINX.12096895077.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: scheme@MIT-MC
Subject: DRAFT of the Revised Revised Report
In-reply-to: Msg of 21 Mar 1985 17:35-EST
Thu 21 Mar 85 13:35:25 est from linus!ramsdell at Mitre-Bedford,
linus!ramsdell (John D. Ramsdell) at Mitre-Bedford
0) I agree that car, cdr, etc, are poor names, yet I have not
seen good alternatives to them except first and rest, which don't nest
(a la c....r) too well. I think that their use is so entrenched that
it would be hard to get used to other things.
Random related comment: A possibility we have not considered
is general-car-cdr:
(general-car-cdr #b1 l) = l
(general-car-cdr #b10 l) = (car l)
(general-car-cdr #b11 l) = (cdr l)
(general-car-cdr #b101 l) = (cadr l)
(general-car-cdr #b110 l) = (cdar l)
etc.
Thus c....r = (lambda (l) (general-car-cdr n l))
Where n = #b1**** with the mapping a->0 b->1
C...r (except car and cdr) are defined like that in MIT
Scheme. Note that general-car-cdr is not limited to a length of 4 for
the chain of car-cdrs, and is trivial to implement.
2 & 5) The reason for not having a different name for the one-armed
IF is that we tried very hard to keep the number of special forms to a
minimum. Since they are easily distinguished by the number of
subforms, there is no need to add another. Note that the same
philosophy leads MIT to have named LET, which is exactly (except for
the name) what ITERATE used to be.
3) I don't think that the syntax (named-lambda name expr) is a
good idea as a substitute for rec. An extension of rec would allow
something like (rec a-circular-list (cons 'a a-circular-list)) where
there are no lambdas, so named-lambda is inappropriate.
Note that both rec and named-lambda are optional, so there is
no need to drop any. Different dialects have preferences for one
over the other, so an arbitrary decision would probably not sit well.
Note also that MIT Scheme allows also the syntax
(named-lambda ((foo . args1) . args2) . body) =
(named-lambda (foo . args1) (lambda args2 . body))
which is not on the report.
9) I don't think that the list? you propose is missing. I think
list? should be defined as
(define (list? l)
(or (null? l) (and (pair? l) (list? (cdr l)))))
, in other words, proper-list?.
What you define as list? is what we (MIT-Scheme) call
weak-list? which we have never found a real use for.
I would like to eliminate the confusion about lists. I
propose that list refer to proper lists, and anything else built out
of pairs be called a pair-graph. Thus lists are pair-graphs but not
viceversa. The procedure LIST produces a list, and the procedure
LIST? tests whether an object is one.
∂22-Mar-85 0951 JAR@MIT-MC (if a b)
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Mar 85 09:50:58 PST
Date: 22 March 1985 12:51-EST
From: Jonathan A Rees <JAR @ MIT-MC>
Subject: (if a b)
To: SCHEME @ MIT-MC
In-reply-to: Msg of 21 Mar 1985 17:35:34-EST
Thu 21 Mar 85 13:35:25 est from linus!ramsdell at Mitre-Bedford,
linus!ramsdell (John D. Ramsdell) at Mitre-Bedford
I'm in agreement with John Ramsdell in opposing amputated IF (although I
also agree with Bill Rozas that WHEN is a bad idea). IF-forms should
always have two arms. Could someone explain to me again why it is a
good idea? It complicates the language. You can always use (COND (test
...)) if you really don't want to write another arm. And your dialect
can optionally include the amputated variant. I don't see how one can
simultaneously support (IF A B) and oppose (DEFINE (FOO X) Y).
Jonathan
∂22-Mar-85 1322 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa ASSERT, ports, and NIL
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Mar 85 13:22:07 PST
Received: from csnet-relay by MIT-MC.ARPA; 22 MAR 85 16:22:23 EST
Received: from ti-csl by csnet-relay.csnet id ac00183; 22 Mar 85 14:11 EST
Date: 22 Mar 1985 1032-CST
From: David Bartley <Bartley%ti-csl.csnet@csnet-relay.arpa>
Subject: ASSERT, ports, and NIL
To: Scheme@mit-mc.ARPA
cc: Bartley%ti-csl.csnet@csnet-relay.arpa
Received: from csl60 by ti-csl; Fri, 22 Mar 85 10:56 CST
I have some miscellaneous comments on topics raised recently...
1. I like Will's ASSERT. I have used the same approach before in
compilers for Pascal and other languages and find that it is quite
appropriate for both the programmer and a dataflow-oriented optimizer.
2. I like PORT. My Webster's includes the following definitions:
(2a) an opening for intake or exhaust of a fluid ...
(2c) a place of access to a system
This is close enough to the concept we have in mind. Frankly, "raft" seems
too whimsical for a language that deserves to be taken seriously.
3. I hate NIL. However, I have a problem of great practical significance
to our work that I'd like help with. As much as I abhor it personally,
Common Lisp equates the empty list, the logical <false> value, and the
symbol NIL. Here at TI's Computer Science Lab, we are building
experimental multi-lingual program development environments for various
machines (including our Explorer Lisp machine) in which Scheme, Common
Lisp, Prolog, and other languages need to co-exist. I see no practical way
to avoid defining our Scheme's #!NULL and #!FALSE as anything other than
the symbol NIL. Otherwise the two languages cannot share list data. If
anyone has a good general solution to this problem, I'd like to hear of it.
If not, I ask that this interpretation be permitted by the revised report.
Surely we aren't the only ones interested in multi-lingual issues?
Regards,
David Bartley
-------
∂22-Mar-85 1325 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa Re: Revisions to String Proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Mar 85 13:25:35 PST
Received: from csnet-relay by MIT-MC.ARPA; 22 MAR 85 16:22:54 EST
Received: from ti-csl by csnet-relay.csnet id ag00183; 22 Mar 85 14:13 EST
Date: 22 Mar 1985 1105-CST
From: David Bartley <Bartley%ti-csl.csnet@csnet-relay.arpa>
Subject: Re: Revisions to String Proposal
To: CPH%MIT-OZ@mit-mc.ARPA, Scheme@mit-mc.ARPA
cc: Bartley%ti-csl.csnet@csnet-relay.arpa
In-Reply-To: Your message of 20-Mar-85 0242-CST
Received: from csl60 by ti-csl; Fri, 22 Mar 85 12:26 CST
I am quite pleased with Chris' revised string proposal.
A minor suggestion -- perhaps the = and < comparators could be made
essential and the <=, >, and >= comparators made optional.
Regards,
David Bartley
-------
∂22-Mar-85 1344 @MIT-MC:GJS@MIT-OZ Re: ASSERT, ports, and NIL
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Mar 85 13:44:42 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 22 MAR 85 16:44:32 EST
Date: Fri 22 Mar 85 16:43:08-EST
From: Gerald Jay Sussman <GJS%MIT-OZ@MIT-MC.ARPA>
Subject: Re: ASSERT, ports, and NIL
To: Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
cc: scheme@MIT-MC
In-Reply-To: Message from "David Bartley <Bartley%ti-csl.csnet@csnet-relay.arpa>" of Fri 22 Mar 85 11:32:00-EST
I like "port" too!
-------
∂22-Mar-85 1353 JAR@MIT-MC NIL
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Mar 85 13:53:38 PST
Date: 22 March 1985 16:52-EST
From: Jonathan A Rees <JAR @ MIT-MC>
Subject: NIL
To: Bartley%ti-csl.csnet @ CSNET-RELAY
cc: SCHEME @ MIT-MC
In-reply-to: Msg of 22 Mar 1985 1032-CST from David Bartley <Bartley%ti-csl.csnet at csnet-relay.arpa>
Date: 22 Mar 1985 1032-CST
From: David Bartley <Bartley%ti-csl.csnet at csnet-relay.arpa>
3. I hate NIL. However, I have a problem of great practical significance
to our work that I'd like help with. As much as I abhor it personally,
Common Lisp equates the empty list, the logical <false> value, and the
symbol NIL. Here at TI's Computer Science Lab, we are building
experimental multi-lingual program development environments for various
machines (including our Explorer Lisp machine) in which Scheme, Common
Lisp, Prolog, and other languages need to co-exist. I see no practical way
to avoid defining our Scheme's #!NULL and #!FALSE as anything other than
the symbol NIL. Otherwise the two languages cannot share list data. If
anyone has a good general solution to this problem, I'd like to hear of it.
If not, I ask that this interpretation be permitted by the revised report.
Surely we aren't the only ones interested in multi-lingual issues?
I don't think we need to or should allow either false or the empty list
to be a symbol. In our PDP-10 Maclisp prototype of T, we solved the
inconsistency by doing (REMOB 'NIL). Maclisp had a symbol NIL, which
was the same as false and the empty list, and T had a symbol NIL
(created, after the REMOB happened, the first time that READ encountered
the sequence "NIL"), which was different from the Maclisp symbol NIL. T
and Maclisp coexisted happily. Then we did:
(defun symbol? (x)
(and x (symbolp x)))
Similarly, in the Common Lisp emulation package in T, we created a
parameter to READ which caused the atom NIL to read in as the empty
list, using the same framework that allows atoms like 1E3 and 5/8 to be
read as numbers instead of symbols. Then, we emulated Common Lisp
symbols as the union of T symbols and the empty list:
(define (symbolp x)
(or (symbol? x) (null? x)))
(define (intern x)
(if (string-equal? x "NIL") ;(no packages)
'()
(string->symbol x)))
(define (symbol-name x)
(xcond ((symbol? x) (symbol->string x))
((null? x) "NIL")))
and so on.
So Common Lisp (with its own environment, syntax table, and read table
distinct from T's) coexisted happily with T.
The much harder problem is emulating the status quo when false and the
empty list are distinguished, but let's not talk about that.
Jonathan
∂22-Mar-85 1835 @MIT-MC:HUDAK@YALE.ARPA Re: DRAFT of the Revised Revised Report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Mar 85 18:34:52 PST
Received: from yale by MIT-MC.ARPA; 22 MAR 85 21:21:48 EST
Received: by YALE-BULLDOG.YALE.ARPA; 21 Mar 85 21:31:50 EST (Thu)
Message-Id: <8503220231.AA28348@YALE-BULLDOG.YALE.ARPA>
Received: from YALE-RING by YALE-RES via CHAOS; Thu, 21 Mar 85 21:28:34 EST
Subject: Re: DRAFT of the Revised Revised Report
Date: Thu, 21 Mar 85 21:28:35 EST
From: Paul Hudak <Hudak@YALE.ARPA>
To: Bill Rozas <JINX%MIT-OZ@MIT-MC>
Cc: scheme@MIT-MC
In-Reply-To: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>, 21 Mar 1985 18:49 EST (Thu)
0) I agree that car, cdr, etc, are poor names, yet I have not
seen good alternatives to them except first and rest, which don't
nest (a la c....r) too well. I think that their use is so
entrenched that it would be hard to get used to other things.
Another possibility is head and tail. Both of them actually *do*
nest fairly well; for example, according to the following scheme:
car&cdr head&tail first&rest
----------------------------------
caar hhd fft
cadr htl frt
cdar thd rft
cddr ttl rrt
caaar hhhd ffft
caadr hhtl ffrt
cadar hthd frft
caddr httl frrt
... ... ...
My personal preference is head and tail, but anything is better than
car and cdr.
-Paul
∂22-Mar-85 2049 @MIT-MC:ANDY@SU-SCORE.ARPA Re: DRAFT of the Revised Revised Report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Mar 85 20:48:54 PST
Received: from SU-SCORE.ARPA by MIT-MC.ARPA; 22 MAR 85 23:49:16 EST
Date: Fri 22 Mar 85 20:47:41-PST
From: Andy Freeman <ANDY@SU-SCORE.ARPA>
Subject: Re: DRAFT of the Revised Revised Report
To: Hudak@YALE.ARPA
cc: JINX%MIT-OZ@MIT-MC.ARPA, scheme@MIT-MC.ARPA
In-Reply-To: Message from "Paul Hudak <Hudak@YALE.ARPA>" of Fri 22 Mar 85 18:36:19-PST
Actually I prefer car/cdr over head/tail and first/rest because the
former have no outside associations (I've never seen a 7094) and the
latter do. I then define more appropriate names that reflect the
meaning in the program. More meaningful (or less ugly) names don't
encourage this. (I'm not sure about -<>-, etc., but they share the
unnecessary topological connotations of head/tail and first/rest.)
Then again, I don't want my cons operations to suggest that I'm
working on lists, just cons'. (Someone has already mentioned the
difference between cons? and list?) Also, car/cdr are nice harmless
bit of history.
-andy
-------
∂24-Mar-85 0007 @MIT-MC:CPH@MIT-OZ
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 24 Mar 85 00:07:05 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 24 MAR 85 03:06:34 EST
Date: Sun, 24 Mar 1985 02:26 EST
Message-ID: <CPH.12097502667.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: Hudak@YALE.ARPA, Jinx%MIT-OZ@MIT-MC.ARPA
Cc: Scheme@MIT-MC
In-reply-to: Msg of 21 Mar 1985 21:28-EST from Paul Hudak <Hudak at YALE.ARPA>
Maybe I'm just being old and tired, but I like CAR and CDR! I would
be saddened to see them lost in a wave of "modernization". Would you
consider changing LAMBDA to something else? I think that CAR, CDR and
CONS have the same historical value (as does COND, I suppose).
Obviously, I like keeping in touch with the past, as long as it
doesn't cloud the thinking of the future. This doesn't seem to be
such a case; might as well call the operations "0" and "1", if you
want to be really, really efficient.
∂24-Mar-85 0009 @MIT-MC:CPH@MIT-OZ Revisions to String Proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 24 Mar 85 00:09:24 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 24 MAR 85 03:06:38 EST
Date: Sun, 24 Mar 1985 02:37 EST
Message-ID: <CPH.12097504585.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Cc: Scheme@MIT-MC.ARPA
Subject: Revisions to String Proposal
In-reply-to: Msg of 22 Mar 1985 12:05-EST from David Bartley <Bartley%ti-csl.csnet at csnet-relay.arpa>
Date: Friday, 22 March 1985 12:05-EST
From: David Bartley <Bartley%ti-csl.csnet at csnet-relay.arpa>
A minor suggestion -- perhaps the = and < comparators could be made
essential and the <=, >, and >= comparators made optional.
I think that this is quite reasonable -- often I try to code this way.
Although... is the cost of tying up these few identifiers worth the
extra expressive power they may bring? I think it probably is;
sometimes it seems that one wants to say "(>= ...)" rather than "(not
(< ...))". The extra symbols will be bound in people's minds whether
or not they are in the "revised revised report" or not.
∂25-Mar-85 1306 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa Re: NIL
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 25 Mar 85 13:06:14 PST
Received: from csnet-relay by MIT-MC.ARPA; 25 MAR 85 15:44:44 EST
Received: from ti-csl by csnet-relay.csnet id ae10480; 25 Mar 85 15:34 EST
Date: 25 Mar 1985 1153-CST
From: David Bartley <Bartley%ti-csl.csnet@csnet-relay.arpa>
Subject: Re: NIL
To: JAR@mit-mc.ARPA, Bartley%ti-csl.csnet@csnet-relay.arpa
cc: SCHEME@mit-mc.ARPA, Bartley%ti-csl.csnet@csnet-relay.arpa
In-Reply-To: Your message of 22-Mar-85 1552-CST
Received: from csl60 by ti-csl; Mon, 25 Mar 85 13:41 CST
Re: Jonathon's suggestion for rationalizing NIL in Common Lisp and () in
Scheme...
When Common Lisp is implemented on top of Scheme, or at the same time as
Scheme, your second approach is quite workable. It relies on making the
representation of the empty list suit Scheme's needs and patching up a few
components of Common Lisp so () "looks" like the symbol NIL. My only
concern here is that I'd like to use the same reader, the same SYMBOL?/
SYMBOLP routine, etc., but I'm willing to give in on those.
The first example you gave, bringing up Scheme (T) on top of Common Lisp
(Maclisp), still has a problem. If Scheme is introduced into a system in
which the idea that NIL=='NIL=='() is deeply ingrained (e.g. in microcode),
then I see no way to allow a user to jump back and forth between processes
written in the two languages and which must share the same list data,
without making 'NIL=='().
I intend to make new systems conform along the lines you suggest. However,
I still would like a multi-lingual implementation built on an existing Lisp
system to be allowed by the standard.
Regards,
David Bartley
-------
∂25-Mar-85 1443 @MIT-MC:linus!ramsdell@mitre-bedford ITERATE
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 25 Mar 85 14:43:21 PST
Received: from mitre-bedford by MIT-MC.ARPA; 25 MAR 85 17:43:15 EST
Date: 25 Mar 1985 17:36:35-EST
From: linus!ramsdell@Mitre-Bedford
Received: by linus.UUCP (4.12/4.7)
id AA25113; Mon, 25 Mar 85 08:01:59 est
Date: Mon, 25 Mar 85 08:01:59 est
From: linus!ramsdell (John D. Ramsdell)
Message-Id: <8503251301.AA25113@linus.UUCP>
To: bccvax!scheme@mit-mc.arpa
Subject: ITERATE
If named LET is to replace ITERATE, that is fine with me.
Please make it an essential form.
John
∂25-Mar-85 1757 @MIT-MC:HUDAK@YALE.ARPA CAR and CDR again
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 25 Mar 85 17:57:48 PST
Received: from yale by MIT-MC.ARPA; 25 MAR 85 20:58:07 EST
Received: by YALE-BULLDOG.YALE.ARPA; 24 Mar 85 19:54:45 EST (Sun)
Message-Id: <8503250054.AA23410@YALE-BULLDOG.YALE.ARPA>
Received: from YALE-RING by YALE-RES via CHAOS; Sun, 24 Mar 85 20:00:23 EST
Subject: CAR and CDR again
Date: Sun, 24 Mar 85 20:00:25 EST
From: Paul Hudak <Hudak@YALE.ARPA>
To: CPH%MIT-OZ@MIT-MC
Cc: Scheme@MIT-MC, Jinx%MIT-OZ@MIT-MC
In-Reply-To: CPH%MIT-OZ@MIT-MC.ARPA, Sun, 24 Mar 1985 02:26 EST
Maybe I'm just being old and tired, but I like CAR and CDR! I
would be saddened to see them lost in a wave of "modernization".
Would you consider changing LAMBDA to something else? I think
that CAR, CDR and CONS have the same historical value (as does
COND, I suppose).
LAMBDA derives from the Lambda Calculus, where the association with
lambda expressions is clear. CAR and CDR derive from obscure machine
features whose meaning is not clear. CONS is not so bad because it
is short for CONSTRUCT, although PAIR would probably be better.
Obviously, I like keeping in touch with the past, as long as it
doesn't cloud the thinking of the future. This doesn't seem to be
such a case; might as well call the operations "0" and "1", if you
want to be really, really efficient.
Efficiency, of course, is not the rationale for any of this. It's
choosing a name that makes sense. Why did we choose names like WALK
instead of the "traditional" MAPC or MAPCAR or whatever? Some people
probably feel as bad about loosing those as they would for CAR and CDR.
However, I'm not one to stand in the way of preserving history! I was
curious to see how people felt though, and wanted to see how far Essential
Scheme's modernization effort, which does exist, was willing to go.
-Paul
∂25-Mar-85 1852 GJC@MIT-MC NIL, experience with VAX-NIL, or NIL is nothing to worry about.
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 25 Mar 85 18:42:39 PST
Date: 25 March 1985 21:43-EST
From: George J. Carrette <GJC @ MIT-MC>
Subject: NIL, experience with VAX-NIL, or NIL is nothing to worry about.
To: Bartley%ti-csl.csnet @ CSNET-RELAY
cc: JAR @ MIT-MC, SCHEME @ MIT-MC
In-reply-to: Msg of 25 Mar 1985 1153-CST from David Bartley <Bartley%ti-csl.csnet at csnet-relay.arpa>
I was able to put a rational, i.e. (NOT (EQ 'NIL '())), scheme on
top of both VAX-NIL and LMI Release 2.0, both of which are common-lisp.
In fact, in the inner guts of VAX-NIL we have that () is not a symbol,
and the first distributed versions of NIL (SYMBOLP ()) => (),
but peer presure forced us (at that time Glenn Burke and myself) to
toe-the-line and change, if not the guts, but what the user sees
in the way of a type scheme.
One argument TYPEP is not supported in common-lisp, so the following
output from VAX-NIL should not be suprising:
(TYPEP ()) => NULL
(TYPEP 'FOO) => SI:NON-NULL-SYMBOL
(TYPEP '(FOO)) => SI:SIMPLE-CONS
Of course (SYMBOLP X) <==> (TYPEP X 'SYMBOL)
<==> (TYPEP X '(OR NULL SI:NON-NULL-SYMBOL)).
LISTP is then (TYPEP X '(OR NULL SI:SIMPLE-CONS SI:EXTENDED-CONS)).
The SI:EXTENDED-CONS is something GSB put in for BRANDX, (remember hunks?)
but lets not get into that.
There are of course special type masks cleverly arranged to be used with the
VAX instructions for doing these type unions, so that the most useful cases
of two-argument TYPEP are in-line-coded.
The inner workings of the microcoded lisps such as on the LMI LAMBDA
and TI EXPLORER play similar hacks with NIL. Its just one of those
things. Unfortunately the Common-Lisp committee, of which I felt like
an out-gunned member, had the "guts" to change MEMBER, ASSOC, EQUAL,
*, /, +,↑, but not to address this NIL thing.
If you reread JAR's analysis, and I hope I have provided some hints
into the inner workings of some of the base lisps in question, then
you should see what he is talking about.
∂26-Mar-85 1439 @MIT-MC:linus!ramsdell@mitre-bedford WHEN
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 26 Mar 85 14:38:06 PST
Received: from mitre-bedford by MIT-MC.ARPA; 26 MAR 85 17:38:09 EST
Date: 26 Mar 1985 17:36:00-EST
From: linus!ramsdell@Mitre-Bedford
Received: by linus.UUCP (4.12/4.7)
id AA09491; Tue, 26 Mar 85 09:43:17 est
Date: Tue, 26 Mar 85 09:43:17 est
From: linus!ramsdell (John D. Ramsdell)
Message-Id: <8503261443.AA09491@linus.UUCP>
To: bccvax!scheme@mit-mc.arpa
Subject: WHEN
OK, so WHEN is a bad idea. However, I agree with
Jonathan that one armed IF is a bad idea.
John
∂26-Mar-85 1444 @MIT-MC:linus!ramsdell@mitre-bedford LIST?
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 26 Mar 85 14:41:00 PST
Received: from mitre-bedford by MIT-MC.ARPA; 26 MAR 85 17:38:57 EST
Date: 26 Mar 1985 17:36:04-EST
From: linus!ramsdell@Mitre-Bedford
Received: by linus.UUCP (4.12/4.7)
id AA09666; Tue, 26 Mar 85 09:54:52 est
Date: Tue, 26 Mar 85 09:54:52 est
From: linus!ramsdell (John D. Ramsdell)
Message-Id: <8503261454.AA09666@linus.UUCP>
To: bccvax!scheme@mit-mc.arpa
Subject: LIST?
Cc: ramsdell
I thought LIST? would be a good name for the predicate
that returns true to the objects generated by LIST,
just an VECTOR? returns true to the objects generated
by VECTOR and PAIR? returns true to the objects generated
by PAIR ... eh ... CONS. Opps! Nevermind.
John
PS Maybe STRING should take a variable number of characters
and returns a string.
(define (string . chars) (list->string chars))
∂26-Mar-85 1501 @MIT-MC:linus!ramsdell@mitre-bedford function names.
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 26 Mar 85 15:01:35 PST
Received: from mitre-bedford by MIT-MC.ARPA; 26 MAR 85 17:39:48 EST
Date: 26 Mar 1985 17:36:09-EST
From: linus!ramsdell@Mitre-Bedford
Received: by linus.UUCP (4.12/4.7)
id AA09753; Tue, 26 Mar 85 10:00:27 est
Date: Tue, 26 Mar 85 10:00:27 est
From: linus!ramsdell (John D. Ramsdell)
Message-Id: <8503261500.AA09753@linus.UUCP>
To: bccvax!scheme@mit-mc.arpa
Subject: function names.
It is clear no agreement can be reached about CAR and CDR.
I withdraw the suggested name changes except for:
MAPCAR => MAP and
MAPC => WALK.
Is there disagreement here?
John
∂26-Mar-85 1659 @MIT-MC:KMP@SCRC-STONY-BROOK function names.
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 26 Mar 85 16:59:45 PST
Received: from SCRC-STONY-BROOK by MIT-MC via Chaosnet; 26 MAR 85 19:59:59 EST
Received: from SCRC-RIO-DE-JANEIRO by SCRC-STONY-BROOK via CHAOS with CHAOS-MAIL id 203900; Tue 26-Mar-85 18:28:31-EST
Date: Tue, 26 Mar 85 18:28 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: function names.
To: linus!ramsdell@MITRE-BEDFORD.ARPA, scheme@MIT-MC.ARPA
In-Reply-To: <8503261500.AA09753@linus.UUCP>
Message-ID: <850326182851.4.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Date: Tue, 26 Mar 85 10:00:27 est
From: linus!ramsdell (John D. Ramsdell)
Message-Id: <8503261500.AA09753@linus.UUCP>
Subject: function names.
It is clear no agreement can be reached about CAR and CDR.
I withdraw the suggested name changes except for:
MAPCAR => MAP and
MAPC => WALK.
Is there disagreement here?
I support these name changes (perhaps not surprisingly since
I'm partly responsible for them being that way in T). For those
who are curious about the justification for the MAPCAR->MAP change:
* MAP is nicely generic. You can't later extend MAPCAR to
work on general structures like matrices without having to
apologize for the fact that "successive cars of a matrix"
is not as meaningful as it is for lists.
* Whenever anyone complained to me that MAP had another
meaning and that people would be confused, I would take
them by the arm and drag them into the office of an
unsuspecting person to whom I would say: "Please write
an expression on the board which maps a function F across
a list L." The person would -always- write
(MAPCAR F L)
No one -ever- wrote
(MAP F L)
The reason is that MAP is so uncommon that no one even
bothers to verbally distinguish it from MAPCAR. You have to
say "Please write an expression which calls the function MAP
on arguments which are the function F and the list L." to get
the other behavior. From this I conclude that it is "natural"
for the MAPCAR operation to be called MAP.
The arguments for MAPC->WALK are these:
MAPCAR returns a value which is intended to be used.
MAPC returns a value which is not intended to be used.
MAPCAR takes a function which is not intended to have a side-effect.
MAPC takes a function which is intended to have a side-effect.
These two functions have little more in common than the fact
that their first arg is a function and the second is a list.
Also, the "C" is pretty random (presumably deriving from the "CAR"
in MAPCAR). As with MAPCAR, if MAPC were ever extended to map across
(notice I'm using the word "map" and you -know- what I mean) matrices,
arrays, vectors, etc. then again the "C" would be still harder to
explain.
So we wanted something that connoted `visiting elements' but not
a priori constraining the way those elements were enumerated and
not connoting any idea of return value. WALK was chosen because it's
short, sounds like what it does ("walks around in structures"), etc.
By the way, T uses MAPCDR and WALKCDR to mean the "less common" variants
(MAPLIST and MAP, respectively, so you don't have to look them up). The
fact that the names are longer is appropriate (common things should get
the short names), as is the fact that the term CDR is included (since
these don't make sense to generalize to non-CDRable things (although if
you generalized CDR, they would make sense and their name would still
be fine)).
To help with this convention, T renames Lisp's traditional LAST function
to LASTCDR, so what is sometimes called LASTCAR can be called LAST (for
naming consistency with MAP/MAPCDR, WALK/WALKCDR, NTH/NTHCDR).
It is this sort of regularization of naming which has led users of T to
spontaneously send fan mail saying how much they like the clarity of
expression the new names encourage. (Most other languages I've seen get
mostly gripes about naming and little or no praise.) What gripes we get
are usually nitpicky things where users (having decided things are really
winning) want to encourage us to go the rest of the way toward making
the naming consistent in the places where we hesitated to make choices
which would clearly have made the language even more regular. Almost no
one has complained of missing an old name (especially since for the cases
where they care, it's so easy to define synonyms).
-kmp
∂26-Mar-85 1703 @MIT-MC:KMP@SCRC-STONY-BROOK How to let macros work without defining what a macro is...
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 26 Mar 85 17:03:06 PST
Received: from SCRC-STONY-BROOK by MIT-MC via Chaosnet; 26 MAR 85 20:00:04 EST
Received: from SCRC-RIO-DE-JANEIRO by SCRC-STONY-BROOK via CHAOS with CHAOS-MAIL id 203911; Tue 26-Mar-85 18:59:50-EST
Date: Tue, 26 Mar 85 19:00 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: How to let macros work without defining what a macro is...
To: Scheme@MIT-MC.ARPA
cc: KMP@SCRC-STONY-BROOK.ARPA
Message-ID: <850326190013.5.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Even though it was not possible to agree on how macros
should be specified in Scheme, I believe it important
that they be provided in some form in all implementations
and have a proposal for a semi-invisible way to do this.
(PRIMITIVE-SYNTAX-EXPAND form) required
Takes any form and returns a form which is guaranteed
not to have any syntax other than that required by
the language.
This function signals an error if it receives a form
which is a user-defined macro. (Hence, this function is
for writing code which is defined only over portable
code). The fact that it only allows "primitive" macros
to be expanded is what makes it not need an ENV argument,
since the primitive language does not allow one to
change the set of special forms.
Actually, there are two variations of this proposal which
are probably consistent. One says that it expands all
levels; the other says that it expands just one level.
I think it really doesn't matter. For consistency with
SYNTAX-EXPAND below, let's assume it doesn't recurse into
the form.
The intent is (though this is not part of the proposal)
that languages providing a macro facility would have a
function:
(SYNTAX-EXPAND form env) optional
Takes any form and a syntax environment and returns
a form which has no other syntax than lisp syntax.
This form will expand macros and call PRIMITIVE-SYNTAX-EXPAND
if the underlying representation makes that necessary.
The result should be a form which contains only primitive forms.
This would allow us to define system extensions which we could
-describe- as macro translations without telling users how those
things were defined. Eg, they might be macros or they might be
special forms. Consider that (function/macro names in this example
being hypothetical, but you'll get the idea I hope):
(WITH-OPEN-FILE (STREAM-VAR FILE-NAME . OPTIONS) . BODY)
might be defined to the user to "be the same as":
(CALL-WITH-OPEN-STREAM (LAMBDA (STREAM-VAR) BODY) FILE-NAME . OPTIONS)
and
(PRIMITIVE-SYNTAX-EXPAND
'(WITH-OPEN-FILE (OUTSTREAM "MY.FILE" 'OUT)
(PRINT "Hi there." OUTSTREAM)))
would be defined to return
(CALL-SYNTAX-EXPAND (LAMBDA (OUTSTREAM) (PRINT "Hi there." OUTSTREAM))
"MY.FILE" 'OUT)
regardless of whether the system actually did that expansion when it
ENCLOSEd the form...
This proposal basically gives the user the ability to maintain the
illusion that there are a fixed set of special forms when he does
code-manipulation even if we later decide that a few extra special forms
would be a good idea. eg, WHEN, UNLESS, etc. would not burden code-walking
writers since (PRIMITIVE-SYNTAX-EXPAND form) would know about those
forms and how to magically make them into something meaningful like COND
or IF (are they both primitive? they wouldn't have to be under this proposal).
This also allows implementations to add new special forms which are not
in standard Scheme but which are still handleable by standard Scheme.
Note well that programs which expect to work on code which might call
user-defined macros would HAVE TO use SYNTAX-EXPAND and could not use
PRIMITIVE-SYNTAX-EXPAND even if PRIMITIVE-SYNTAX-EXPAND would appear to
work, since PRIMITIVE-SYNTAX-EXPAND should NOT be sensitive to any
redefinitions of system primitive special forms that extended Scheme
implementations might allow. That is, if a dialect allowed
(DEFINE-SYNTAX (IF ...) ...variant-definition...)
then
(SYNTAX-EXPAND '(IF ...)) should get the variant expansion but
(PRIMITIVE-SYNTAX-EXPAND '(IF ...)) should get the "standard expansion".
This is completely necessary in order for any of this proposal to make sense.
∂26-Mar-85 1802 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa Missing CSNET messages
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 26 Mar 85 18:02:33 PST
Received: from csnet-relay by MIT-MC.ARPA; 26 MAR 85 20:56:28 EST
Received: from ti-csl by csnet-relay.csnet id ab19022; 26 Mar 85 20:19 EST
Date: 26 Mar 1985 1637-CST
From: David Bartley <Bartley%ti-csl.csnet@csnet-relay.arpa>
Subject: Missing CSNET messages
To: Scheme@mit-mc.ARPA
cc: Bartley%ti-csl.csnet@csnet-relay.arpa,
Scheme.users%ti-csl.csnet@csnet-relay.arpa
Received: from csl60 by ti-csl; Tue, 26 Mar 85 19:16 CST
A failure at our end caused TI-CSL to miss messages directed to it
yesterday. Would anyone who sent a message to me (Bartley@TI-CSL) or
indirectly to us through Scheme@MIT-MC please resend their messages?
Senders include:
MW@Brandeis
JAR@MIT-MC
linus!ramsdell...
the CSNET postmaster
GJC@MIT-MC
HUDAK%YALE@MIT-MC.ARPA
I don't know how to interpret some of the addresses that failed. We
apparently received messages for "Scheme@Users" which were rejected. Our
local Scheme group mailing list is Scheme.Users@TI-CSL, if that's what
you're looking for.
Regards,
David Bartley
-------
∂26-Mar-85 1839 @MIT-MC:GJS@MIT-OZ car/cdr
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 26 Mar 85 18:39:40 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 26 MAR 85 21:39:06 EST
Date: Tue 26 Mar 85 21:37:53-EST
From: Gerald Jay Sussman <GJS%MIT-OZ@MIT-MC.ARPA>
Subject: car/cdr
To: hudak@YALE.ARPA
cc: scheme@MIT-MC
I dunno if I ever responded to you about this, but I really like
CAR, CDR, CADADR and all the rest. The special advantage is that they
can be pronounced, so I can say them fast over the phone to someone and
they can be expected to understand what I said. Imagine having to say
"First of Rest of First of Rest" when one can say "CADADR"... The key is
that combinations of "A" and "D" are not tongue-twisters.
I think that this is the only name convention I really am attached to, and
it is NOT for historical (hysterical?) reasons, but pragmatic ones.
-------
∂27-Mar-85 0212 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Re: DRAFT of the Revised Revised Report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 27 Mar 85 02:12:11 PST
Received: from csnet-relay by MIT-MC.ARPA; 27 MAR 85 05:12:36 EST
Received: from unc by csnet-relay.csnet id ac21376; 27 Mar 85 5:04 EST
Received: by unc (4.12/4.7) id AA21906; Wed, 27 Mar 85 01:25:03 est
Date: Wed, 27 Mar 85 01:25:03 est
From: Kent Dybvig <dyb%unc.csnet@csnet-relay.arpa>
Message-Id: <8503270625.AA21906@unc>
To: scheme@mit-mc.ARPA
Subject: Re: DRAFT of the Revised Revised Report
2 & 5) The reason for not having a different name for the one-armed
IF is that we tried very hard to keep the number of special forms to a
minimum. Since they are easily distinguished by the number of
subforms, there is no need to add another. Note that the same
philosophy leads MIT to have named LET, which is exactly (except for
the name) what ITERATE used to be.
I used to have both one-armed "if" and named "let" in my system. I got
tired of explaining that the return value of "if" is defined if there
are two arms but undefined if there is one arm. With "let", I got
tired of explaining that it creates simple bindings in the one case
and performs looping/recursion in the other. "let" is such an important
special form that it is inappropriate to give it two such different
meanings.
If you have two syntaxes for one special form, then you have two special
forms. The only difference is that they are distinguished by more than
just the syntax keyword. If one of the two is a natural extension of the
other, fine, otherwise the situation leads to unwarranted confusion.
(The "number of subforms" is an easy distinction for a compiler, but not
always for the eye. I prefer the distinction to be more obvious.)
Incidentally, I had named "let" in my system to correspond to named
"lambda", so named "let" was easy to explain in terms of named "lambda".
Of course, the destructuring lambda-list syntax blew that away.
Conclusions:
I prefer to include "when" and "unless". Cond is not an acceptable
alternative; it is best used to reduce nesting in long sequences of
"if-then-else-if" expressions. While we're at it, I'd like to see
both "cond" and "case" require an "else" clause.
I also prefer the name "recurse" to "iterate" or named "let", and would
like to see it required by the standard.
..Kent
∂27-Mar-85 0638 @MIT-MC:JINX@MIT-OZ function names.
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 27 Mar 85 06:38:20 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 27 MAR 85 09:38:40 EST
Date: 27 Mar 1985 09:37 EST (Wed)
Message-ID: <JINX.12098367479.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: linus!ramsdell@MITRE-BEDFORD.ARPA, scheme@MIT-MC.ARPA
Subject: function names.
In-reply-to: Msg of 26 Mar 1985 17:36-EST
Tue 26 Mar 85 10:00:27 est from linus!ramsdell at Mitre-Bedford,
linus!ramsdell (John D. Ramsdell) at Mitre-Bedford
What does WALK stand for? Something like FOR-EACH would be
better (except that it suggests the opposite order for the arguments).
WALK suggests something that performs a tree walk to me.
∂27-Mar-85 0709 @MIT-MC:JINX@MIT-OZ DRAFT of the Revised Revised Report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 27 Mar 85 07:09:34 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 27 MAR 85 10:09:51 EST
Date: 27 Mar 1985 10:08 EST (Wed)
Message-ID: <JINX.12098373078.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Kent Dybvig <dyb%unc.csnet@CSNET-RELAY.ARPA>
Cc: scheme@MIT-MC.ARPA
Subject: DRAFT of the Revised Revised Report
In-reply-to: Msg of 27 Mar 1985 01:25-EST from Kent Dybvig <dyb%unc.csnet at csnet-relay.arpa>
(define (number-of-special-forms-in-standard date)
(expt 2 (date->number date)))
Now seriously,
Named let corresponds to named-lambda in the same way that let
corresponds to lambda. If argument list destructuring is not a
problem for let, it is not a problem for named let. If it is, the
only "destructuring" allowed in lambda is for &rest arguments (dot
notation). The syntax for LET can be extended to accept rest
arguments:
Note: Each of the subforms of the binding list of a let must be a
list whose CAR is the identifier and whose CADR is the expression
whose value the identifier will receive. Thus the syntax can be
extended to the following:
(let ((<identifier 1> <exp 1>)
.
.
.
(<identifier n> <exp n>)
<rest identifier> ; Note: no parens
<rest exp 1>
.
.
.
<rest exp m>)
<body>)
The rest identifier can be recognized by not being in a list,
and all forms following it are the expressions whose values will be
collected into the &rest list.
I'm not advocating for this extension in the standard, but any
implementation which wants named-let can easily extend the syntax for
let and named-let so that this "destructuring" is provided.
You may be right in that this means that there are 2 special
forms with the same keyword, but that's alright with me. I don't want
to have to remember 50 thousand different identifiers which are
"special" to ths system, and I cannot use as identifiers in portable
code since I don't know what happens in all implementations when a
lambda-parameter attempts to shadow them.
I have no problems recognizing one-armed ifs. They only
appear in the middle of sequences (sorry, begins) and indentation
allows me to see whether there is a second arm or not.
∂27-Mar-85 0722 @MIT-MC:JINX@MIT-OZ How to let macros work without defining what a macro is...
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 27 Mar 85 07:21:59 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 27 MAR 85 10:20:54 EST
Date: 27 Mar 1985 10:19 EST (Wed)
Message-ID: <JINX.12098375135.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Cc: Scheme@MIT-MC.ARPA
Subject: How to let macros work without defining what a macro is...
In-reply-to: Msg of 26 Mar 1985 19:00-EST from Kent M Pitman <KMP at SCRC-STONY-BROOK.ARPA>
This assumes that all macros work at the s-expression level,
which is not true in our implementation. The only way to provide both
(especially syntax-expand) in all cases would be to fully reduce to
s-code and then invert to s-expressions. This would imply full
(recursive) expansion always.
In our system macros translate from s-expressions to s-code.
There are a few utilities, however, to emulate s-expression level
macros built on top of this. But macros like COND, LET, etc are never
translated at the s-expression level.
∂27-Mar-85 0727 @MIT-MC:JINX@MIT-OZ LIST? -- LIST
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 27 Mar 85 07:27:18 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 27 MAR 85 10:24:48 EST
Date: 27 Mar 1985 10:23 EST (Wed)
Message-ID: <JINX.12098375866.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
Subject: LIST? -- LIST
To: linus!ramsdell@MITRE-BEDFORD.ARPA, SCHEME@MIT-MC
LIST? will return true of those objects generated by LIST.
That is precisely the case. The previous proposed definition
for LIST? would return true of things which are not propoer lists, but
LIST can only generate proper lists. Since there is no way (that I
know of) of knowing whether a paricular pair-tree was created by a
call to LIST or not (besides the fact that it seems undesirable), the
only way to make this consistent is for LIST? to return #!true only on
proper lists.
∂27-Mar-85 0808 GJC@MIT-MC plea for macros
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 27 Mar 85 08:08:32 PST
Date: 27 March 1985 11:08-EST
From: George J. Carrette <GJC @ MIT-MC>
Subject: plea for macros
To: SCHEME @ MIT-MC
How about biting the bullet and admitting macros in a way such that
the language can have only one special form: LAMBDA, and all other
forms are defined as macros, even "IF". (To repeat something I've
either seen in a scheme paper or a scheme compiler:
(IF A B C) => (*IF A (LAMBDA () B) (LAMBDA () C)), where *IF is
a hand-coded SUBR). The proper packaging of macros and macro namespaces
would put a lot of budding languages designers amoung us out of business.
Think of scheme as an OEM oriented language. The designers can supply
not much more than the primitives used a "Structure and Interpretation"
the essential ideas and tools, then all manner of interesting (or not)
things can be built on these without being the responsibility of
the designer.
The fact is that there are very large, useful, and even intrinsically
interesting lisp programs that are built on very few primitives. Case
in point: Macsyma. In order to do Macsyma in what common-lisp provides
I had to write my own versions of: GET, EQUAL, ASSOC, PUTPROP, +, -, /, ↑, \,
MEMBER, MAP, MAPLIST. One page of code, big deal.
∂27-Mar-85 1123 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa Re: ASSERT, ports, and NIL
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 27 Mar 85 11:23:41 PST
Received: from csnet-relay by MIT-MC.ARPA; 27 MAR 85 14:24:01 EST
Received: from ti-csl by csnet-relay.csnet id ac23602; 27 Mar 85 14:14 EST
Date: 27 Mar 1985 1038-CST
From: David Bartley <Bartley%ti-csl.csnet@csnet-relay.arpa>
Subject: Re: ASSERT, ports, and NIL
To: Bartley%ti-csl.csnet@csnet-relay.arpa, Scheme@mit-mc.ARPA
cc: Bartley%ti-csl.csnet@csnet-relay.arpa
In-Reply-To: Your message of 22-Mar-85 1032-CST
Received: from csl60 by ti-csl; Wed, 27 Mar 85 12:16 CST
I'd like to clarify my dilemma concerning NIL. Jonathon Rees has shown,
correctly, that one has no problem meeting both the Common Lisp and
standard Scheme specifications for the empty list when the Scheme developer
is able to affect the implementation of both languages. In that case, the
underlying representation for the empty list is arbitrary (call it #!NULL).
The Scheme reader treats the token NIL as a symbol. The Common Lisp reader
interns the token NIL as #!NULL, and such critical routines as SYMBOLP and
INTERN are modified to pretend that the value named #!NULL is a symbol.
The situation I am concerned about is one in which Scheme is being
implemented on top of an existing Lisp system which we are unable to
modify. This is clearly a short term problem, but quite real while it
lasts, and surely not unique to us. For example, it is a problem with
Scheme implementations in Franz Lisp, and in ZetaLisp on Lisp Machines with
()==NIL hardwired into microcode.
Let me walk through an instance of the problem. Assume an existing Lisp in
which ()==NIL. In Lisp, generate a list; the list will be "terminated"
with the symbol NIL in the last CDR. Pass the list to a Scheme routine,
which cdr's down it until it reaches -- what? Unless #!NULL==NIL, Scheme
can't detect the end of the list with a simple EQ? test. Sharing of list
data between the two languages is effectively ruled out.
Again: I'm not arguing that allowing #!NULL==NIL is "good," because it
certainly isn't. I'm just asking for help in overcoming it and, barring a
true solution, insertion of appropriate language in the revised revised
Report acknowledging that it may be a necessity in some implementations.
Alternatively, we could consider such an implementation a "near Scheme" and
take the long term view that it is an interim step towards a "true Scheme."
My purpose here is to raise the issue and possibly find a solution I hadn't
thought of, not to quibble over legalities.
Regards,
David Bartley
-------
∂27-Mar-85 1140 @MIT-MC:ADAMS@YALE.ARPA Re: DRAFT of the Revised Revised Report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 27 Mar 85 11:40:20 PST
Received: from yale by MIT-MC.ARPA; 27 MAR 85 14:40:41 EST
Received: by YALE-BULLDOG.YALE.ARPA; 27 Mar 85 14:30:17 EST (Wed)
Message-Id: <8503271930.AA25200@YALE-BULLDOG.YALE.ARPA>
Received: from YALE-RING by YALE-RES via CHAOS; Wed, 27 Mar 85 14:28:58 EST
Subject: Re: DRAFT of the Revised Revised Report
Date: Wed, 27 Mar 85 14:29:07 EST
From: Norman Adams <Adams@YALE.ARPA>
To: Kent Dybvig <dyb%unc.csnet@CSNET-RELAY>
Cc: scheme@MIT-MC
In-Reply-To: Kent Dybvig <dyb%unc.csnet@csnet-relay.ARPA>, Wed, 27 Mar 85 01:25:03 est
I also prefer the name "recurse" to "iterate" or named "let", and would
like to see it required by the standard.
As far as I can tell, "recurse" is not (yet!) an English word. I think
"recur" would be better, though even that doesn't seem great.
-------
∂27-Mar-85 1143 @MIT-MC:cth%indiana.csnet@csnet-relay.arpa Re: Draft of R.R. Report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 27 Mar 85 11:43:12 PST
Received: from csnet-relay by MIT-MC.ARPA; 27 MAR 85 14:41:26 EST
Received: from indiana by csnet-relay.csnet id ac23683; 27 Mar 85 14:32 EST
Date: Wed, 27 Mar 85 13:22:21 est
From: Chris Haynes <cth%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA04491; Wed, 27 Mar 85 13:22:21 est
To: scheme@mit-mc.ARPA
Subject: Re: Draft of R.R. Report
We are quite pleased with the report. Its synthesis is particularly
remarkable given the considerable diversity of opinion expressed on the
net. Asside from a few bugs and editorial suggestions communicated
directly to Will (the most significant of which was that we agreed
CALL-WITH-CURRENT-CONTINUATION was essential), our only remaining
difficulties with the proposal are reflected in the following opinions.
Given (1) the failure to specify under what circumstance an escape
procedure invocation will result in closing a port opened with
CALL-WITH-INPUT-FILE or CALL-WITH-OUTPUT-FILE, and (2) the optional
nature of the explicit open and close operations, the result is that
portable code can not be written for applications in which ports must
be closed (often the case with todays operating systems) and escape
procedures must be used (as in a coroutine application). The simplest
solution is to make the open and close operations essential and the
call-with operations optional. (In general, if an essential feature
can not be fully specified, it should always be possible to program
around the uncertainty.) If there is some reason why the open and close
operations can not be essential (which shouuld be spelled out in a
rationale statement), then the call-with functions should close files
*only* when they return to the continuation of their invocation. It
would then be possible to define the open and close operations using
call-with functions and devious application of escape procedures.
READ-CHAR-READY? is more descriptive than LISTEN?. The failure to
specify what it returns at end of file is most unfortunate. We
shouldn't waffle just because Common Lisp got it wrong.
If you need to READ with assurance that you won't block, you have to
write your own reader using READ-CHAR-READY? and READ-CHAR?. How
about adding READ-READY?, which returns true iff an entire parsable
object can be read without blocking. (A system that includes READ-ATOM
should also include READ-ATOM-READY?.)
An alternative to this predicate proliferation is to allow all read
functions to return a distinguished object to indicate blocked input,
as they may return a distinguished object to indicate end-of-file.
Then all we need is a single predicate for this object, say HUNG?.
The inclusion of the same numeric order predicates with and without a
"?" looks terrible--as if we couldn't make up our mind, which is what
standardization is all about. And both forms are essential! We were
among of those who insisted on the simpler (no ?) forms because that is
what we were accustomed to. But we'd rather switch than fight if the
result is such conspicuous failure to standardize. At the very least,
only one form should be essential. Would anyone else be willing to
switch?
#!TRUE, #!FALSE and #!NULL should not be constants. They are
sufficiently ugly in programs that an extra quote mark in front is
hardly worse. If they are required more than occasionally they should
be bound to variables anyway. Why complicate the spartan syntax of
Scheme with such things?
#!NULL is unnecessary, for we already have a prefectly good way of
printing and reading the empty list, (). #!NULL is also misnamed:
traditionally NULL is a predicate and NIL is the empty list.
RECURSE (introduced in Chez Scheme and added to Scheme 84) is much
better than "named let" or ITERATE. If we can not agree, it would
be better if neither RECURSE nor named let were mentioned in the report;
but if the standard says some implementations permit named let, it
should say others permit RECURSE.
DEFINE! and DEFREC! should go away. (Yes, We were among those who
wanted them originally, but they aren't worth it.) We're not fond of
DEFINE either and wish it could go the same way, or at least be
optional.
NUMBER? is redundant, since all all numbers are complex in the
proposal. If NUMBER? is included to allow for future generalization
(quaternions?) or other reasons, then the rationale should be stated.
WHEN is better than no one arm conditional. Having no one arm
conditional is better than having IF's alternative optional. UNLESS we
are better off without.
The interaction of OBJECT-HASH and OBJECT-UNHASH with garbage
collection should be specified. If we can't decide, the whole section
should be deleted.
A unary constructor is so fundamental that it is worth standardizing.
It might be called BOX, REF or CELL. BOX probably would create the
least confusion. Of course, we would also need associated selection,
mutation and predicate functions.
Chris
Dan
∂27-Mar-85 1207 @MIT-MC:GJS@MIT-OZ flames!
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 27 Mar 85 12:07:38 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 27 MAR 85 15:06:53 EST
Date: Wed 27 Mar 85 15:05:41-EST
From: Gerald Jay Sussman <GJS%MIT-OZ@MIT-MC.ARPA>
Subject: flames!
To: scheme@MIT-MC
Apparently everyone is hot-under-the-collar about one-armed IF!
I cannot, for the life of me, see the harm of having one-armed IF.
It is totally unambiguous, and it does not eat up a reserved word,
what is more, it is useful. The alternative of WHEN is just feeping
creaturism, as far as I can see.
Just to add some fuel to the controversy, let me make a horrifying
suggestion:
(if p q) should be defined.
It should return #!true if p is false, and it should return
the value of q if p is true. This conflicts with no current
usage since everyone agrees that one should not use the value
of a side-effect operation. On the other hand, it gives IF the
value of logical implication, in the boolean case -- an often
useful feature. For example:
(if (if p q) r s)
-------
∂27-Mar-85 1242 @MIT-MC:JINX@MIT-OZ ASSERT, ports, and NIL
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 27 Mar 85 12:42:00 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 27 MAR 85 15:30:35 EST
Date: 27 Mar 1985 15:27 EST (Wed)
Message-ID: <JINX.12098431230.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Cc: Scheme@MIT-MC.ARPA
Subject: ASSERT, ports, and NIL
In-reply-to: Msg of 27 Mar 1985 11:38-EST from David Bartley <Bartley%ti-csl.csnet at csnet-relay.arpa>
I don't understand the problem.
NULL? is essential, and as far as I know it is the only
appropriate way to detect an empty list.
How NULL? is implemented (in terms of EQ?, etc) is irrelevant.
As far as I'm concerned there are multiple list terminators
all of which are NULL?
∂27-Mar-85 1245 @MIT-MC:JINX@MIT-OZ Draft of R.R. Report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 27 Mar 85 12:45:10 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 27 MAR 85 15:38:18 EST
Date: 27 Mar 1985 15:36 EST (Wed)
Message-ID: <JINX.12098432860.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Chris Haynes <cth%indiana.csnet@CSNET-RELAY.ARPA>
Cc: scheme@MIT-MC.ARPA
Subject: Draft of R.R. Report
In-reply-to: Msg of 27 Mar 1985 13:22-EST from Chris Haynes <cth%indiana.csnet at csnet-relay.arpa>
I agree that #!NULL is unnecessary, but I don't agree that
#!FALSE, etc should be quoted or that they should be bound to
variables if used often. How come you don't ask for 0 to be quoted or
bound to a variable if used often?
RECURSE has the same bug that ITERATE has. The name implies a
certain behaviour which the process it develops may not conform to. In
particular, I usually use named let for loops, but I also use it for
recursive procedures. The advantage of named let is that its name has
no connotations, and that it reduces the number of "reserved"
keywords.
How am I supposed to define things if both DEFINE! and DEFINE
go away?
While I agree that CELLs are nice, why are they neccesary?
They can easily be emulated with pairs, and any implementation which
really uses them can support them optionally.
∂27-Mar-85 1644 @MIT-MC:linus!ramsdell@mitre-bedford Scheme names
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 27 Mar 85 16:44:31 PST
Received: from mitre-bedford by MIT-MC.ARPA; 27 MAR 85 19:44:51 EST
Date: 27 Mar 1985 19:39:08-EST
From: linus!ramsdell@Mitre-Bedford
Received: by linus.UUCP (4.12/4.7)
id AA25130; Wed, 27 Mar 85 10:45:05 est
Date: Wed, 27 Mar 85 10:45:05 est
From: linus!ramsdell (John D. Ramsdell)
Message-Id: <8503271545.AA25130@linus.UUCP>
To: bccvax!scheme@mit-mc.arpa
Subject: Scheme names
When is said that I thought one armed IF is a bad idea,
I really meant that having both a one armed IF and a two
armed IF called the same thing is a bad idea. I can
live without one armed IF because it is trivial to write
the obvious WHEN macro or use COND. Kent points out that the same
problem occurs with named LET. Thus I withdraw my support
for named LET syntax, and request ITERATE (maybe called LOOP)
become an essential form.
I would like to echo KMP's statements about regularization of
naming in T. It is great! Even with a small programming language
like Scheme, it should be the case that one needs to memorize a
small set of naming rules, from which one can correctly guess the
name of the particular function of interest. With T, I am noticely
less dependent on having a manual by my side.
I find it hard to believe that no standardization of macros is
attempted by the Scheme Report, and hope that KMP's macro suggestion
is given serious consideration.
John
∂27-Mar-85 1726 JAR@MIT-MC NIL, again
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 27 Mar 85 17:26:16 PST
Date: 27 March 1985 20:26-EST
From: Jonathan A Rees <JAR @ MIT-MC>
Subject: NIL, again
To: Bartley%ti-csl.csnet @ CSNET-RELAY
cc: SCHEME @ MIT-MC
Date: 27 Mar 1985 1038-CST
From: David Bartley <Bartley%ti-csl.csnet at csnet-relay.arpa>
Let me walk through an instance of the problem. Assume an existing Lisp in
which ()==NIL. In Lisp, generate a list; the list will be "terminated"
with the symbol NIL in the last CDR. Pass the list to a Scheme routine,
which cdr's down it until it reaches -- what? Unless #!NULL==NIL, Scheme
can't detect the end of the list with a simple EQ? test. Sharing of list
data between the two languages is effectively ruled out.
I don't agree that things are hopeless. I will risk repetition in hope
of promoting understanding; my apologies if this message adds nothing to
what I've already said. To implement Scheme on top of a Lisp which
identifies #!NULL (i.e. (), false) with Lisp's symbol NIL, create a new,
unique object; call it SCHEME:NIL. Use this object to implement "the"
symbol NIL for Scheme. Use the object #!NULL, which in Lisp is a symbol
and in Scheme is not, to represent both the empty list and false in
Scheme.
So you have the following equations:
Lisp: Scheme:
Symbol <=> Symbol-but-not-#!NULL
SCHEME:NIL <=> The symbol NIL
NIL, () <=> (), #!NULL, #!FALSE
The phrase "the symbol NIL" is confusing. You need to say either "the
Scheme symbol NIL" or "the Lisp symbol NIL". Lisp and Scheme may agree
on what the empty list and false are, without agreeing on what "the
symbol NIL" is.
(define (symbol? x)
(and x
(or (eq? x 'nil) ;This code is read using the Scheme reader!
(lisp:symbolp x))))
(define (symbol->string x)
(cond ((eq? x 'nil) "NIL")
((not x) (error ...))
(else (lisp:symbol-name x))))
(define (string->symbol x)
(cond ((string-equal? x "NIL") 'nil)
(else (lisp:intern x *scheme-package*))))
(define (null? x) (lisp:null x))
In Common Lisp, these definitions need not be quite so verbose, if you
arrange for the object SCHEME:NIL to be a Common Lisp symbol whose print
name is "NIL" (not EQ to () !).
I do not believe that you will run into trouble if you take this
approach. Since the list terminator is the same between Lisp and
Scheme, there is no problem sharing list structure.
If you plan to use the Common Lisp reader to read Scheme expressions,
then you are in a bit of trouble; Common Lisp allows some way to define
octathorp read macros (so you can implement Scheme #!..., #I, etc.), but
no way to influence the atom reader. But won't you have all sorts of
trouble with numbers if you don't change the atom reader?
I find it hard to believe that you would not be able to make the trivial
required change (the addition of a single COND clause, no more than two
lines of code!). If this patch is really impossible, and you cannot use
a different reader (another tractable solution), then indeed I agree you
will be forced to equate Scheme's NIL with (). I'm sure that would be
fine as an interim solution. The symbol/false distinction is too
useful, and likely to be too ingrained in programs, to permit deviation
from it in the R.R. (although I agree that legalities are not at issue
here).
Jonathan
∂28-Mar-85 0611 @MIT-MC:KMP@SCRC-STONY-BROOK How to let macros work without defining what a macro is...
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Mar 85 06:11:32 PST
Received: from SCRC-STONY-BROOK by MIT-MC via Chaosnet; 28 MAR 85 09:11:51 EST
Received: from SCRC-RIO-DE-JANEIRO by SCRC-STONY-BROOK via CHAOS with CHAOS-MAIL id 204535; Wed 27-Mar-85 19:34:21-EST
Date: Wed, 27 Mar 85 19:34 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: How to let macros work without defining what a macro is...
To: JINX@OZ.MIT
cc: Scheme@MIT-MC.ARPA
In-Reply-To: <JINX.12098375135.BABYL@MIT-OZ>
Message-ID: <850327193441.0.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Date: 27 Mar 1985 10:19 EST (Wed)
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
This assumes that all macros work at the s-expression level,
which is not true in our implementation. The only way to provide both
(especially syntax-expand) in all cases would be to fully reduce to
s-code and then invert to s-expressions. This would imply full
(recursive) expansion always.
In our system macros translate from s-expressions to s-code.
There are a few utilities, however, to emulate s-expression level
macros built on top of this. But macros like COND, LET, etc are never
translated at the s-expression level.
No, you missed the point. You can implement these special forms however
you want. What I'm proposing is something that takes forms which may be
in an extended syntax and translates it into a standard syntax.
eg, suppose the only extended forms in some dialect are WHEN and UNLESS.
Regardless of how those are implemented (perhaps directly represented
in S-code, perhaps translated to something else in S-code, whatever),
all you have to provide is (literally) the following function:
(DEFINE (PRIMITIVE-SYNTAX-EXPAND FORM)
(COND ((ATOM FORM) FORM)
((EQ (CAR FORM) 'WHEN)
`(COND (,(CADR FORM) ,@(CDDR FORM))))
((EQ (CAR FORM) 'UNLESS)
`(COND ((NOT ,(CADR FORM)) ,@(CDDR FORM))))
(T FORM)))
You never have to call the function internally in the system. It simply
has to be available for users who want to use it. It must be the
responsibility of system maintainers to keep it up to date so that
code-manipulating tools can be written which assume a fixed number
of special forms and new special forms can later be added to standard
Scheme which do not cause a need to rewrite those tools.
Suppose that the only special forms we could agree on being standard
were LAMBDA, QUOTE, and SETQ. Suppose that someone insisted that
(IF X Y Z)
had to be written
(*IF (LAMBDA () X)
(LAMBDA () Y)
(LAMBDA () Z))
and *IF had to be a function, etc. Assume similar rewrites were suggested
for other special forms. Now consider a user program in a particular
dialect which had extra special forms (eg, DEFINE, COND, ...):
(DEFINE (USED-FREE-IN EXP VAR TAIL?)
(COND ((ATOM VAR) (EQ EXP VAR))
(FLAG
(COND ((NULL EXP) NIL)
((USED-FREE-IN (CAR EXP) VAR NIL) T)
(T
(USED-FREE-IN (CDR EXP) VAR T))))
((EQ (CAR EXP) 'LAMBDA)
(COND ((MEMQ VAR (CADR EXP)) NIL)
(T
(USED-FREE-IN (CDDR EXP) VAR T))))
((EQ (CAR EXP) 'SETQ)
(OR (EQ EXP (CADR FORM))
(USED-FREE-IN (CADDR EXP) VAR NIL)))
((EQ (CAR EXP) 'QUOTE) NIL)
(T
(USED-FREE-IN EXP VAR T))))
If I didn't blow it, this program "works" on input which contains
LAMBDA, SETQ, and QUOTE but does not work on input that contains
COND, etc. It could, however, work on those, too, by simply making it
say:
(DEFINE (USED-FREE-IN EXP VAR TAIL?)
(LET ((EXP (PRIMITIVE-SYNTAX-EXPAND EXP)))
(COND ((ATOM VAR) (EQ EXP VAR))
(FLAG
(COND ((NULL EXP) NIL)
((USED-FREE-IN (CAR EXP) VAR NIL) T)
(T
(USED-FREE-IN (CDR EXP) VAR T))))
((EQ (CAR EXP) 'LAMBDA)
(COND ((MEMQ VAR (CADR EXP)) NIL)
(T
(USED-FREE-IN (CDDR EXP) VAR T))))
((EQ (CAR EXP) 'SETQ)
(OR (EQ EXP (CADR FORM))
(USED-FREE-IN (CADDR EXP) VAR NIL)))
((EQ (CAR EXP) 'QUOTE) NIL)
(T
(USED-FREE-IN EXP VAR T)))))
The user could write PRIMITIVE-SYNTAX-EXPAND himself, but he'd have
to:
(a) Make sure his understanding of the syntax equivalences was
letter perfect (the system implementors have a better chance
of getting this right)
(b) Update the function every time the dialect changed. ie, adding
a special form if PRIMITIVE-SYNTAX-EXPAND is not a system primitive
function is an incompatible change, but is a compatible change
if PRIMITIVE-SYNTAX-EXPAND is kept in synch with available special
forms.
It would be possible to have forms which were not translatable. They
should simply be advertised as such and PRIMITIVE-SYNTAX-EXPAND should err
when it sees them so that the user doesn't think he's winning when he's
not.
Does this make it clearer?
-kmp
∂28-Mar-85 0717 @MIT-MC:HUDAK@YALE.ARPA IF and WHEN
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Mar 85 07:17:19 PST
Received: from yale by MIT-MC.ARPA; 28 MAR 85 10:17:42 EST
Received: by YALE-BULLDOG.YALE.ARPA; 28 Mar 85 10:04:59 EST (Thu)
Message-Id: <8503281504.AA07856@YALE-BULLDOG.YALE.ARPA>
Received: from YALE-RING by YALE-RES via CHAOS; Thu, 28 Mar 85 10:02:02 EST
Subject: IF and WHEN
Date: Thu, 28 Mar 85 10:02:05 EST
From: Paul Hudak <Hudak@YALE.ARPA>
To: scheme@MIT-MC
Cc:
Invalid-Addresses: JINX@OZ.MIT.ARPA (?Invalid domain (host))
The issue of IF vs. WHEN came up when this mailing-list was first
set up, at which time I responded in favor of WHEN. I'd like to say
again why: when I read other people's code and come across an IF,
I almost always search to see if there is a second arm. The bad thing
about this is that if I don't see one I look harder, carefully matching
parens, to make sure I didn't miss it. I don't buy the "indentation"
argument, because one shouldn't trust other people to follow stylistic
conventions. Simply from a readability standpoint, WHEN is a good
idea, but at least we should require that IF have two arms.
"Feeping creaturism" is not always bad...
-Paul
∂28-Mar-85 0753 @MIT-MC:JINX@MIT-OZ IF and WHEN
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Mar 85 07:53:38 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 28 MAR 85 10:53:13 EST
Date: 28 Mar 1985 10:52 EST (Thu)
Message-ID: <JINX.12098643202.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Paul Hudak <Hudak@YALE.ARPA>
Cc: scheme@MIT-MC
Subject: IF and WHEN
In-reply-to: Msg of 28 Mar 1985 10:02-EST from Paul Hudak <Hudak at YALE.ARPA>
Do you use EMACS? If so C-M-F (Lisp or SCheme Modes) does the
job when you're confused. I didn't mean counting parens.
∂28-Mar-85 0803 @MIT-MC:JINX@MIT-OZ syntax-expand
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Mar 85 08:03:50 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 28 MAR 85 11:04:12 EST
Date: 28 Mar 1985 11:02 EST (Thu)
Message-ID: <JINX.12098645186.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
Subject: syntax-expand
To: kmp@MIT-MC
cc: scheme@MIT-MC
I don't think you understood my message. I was not saying
that we shouldn't have them, just that providing single level
expansion (especially for syntax-expand in the presence of macros) may
not be so easy. Since you left open the possibility for full
expansion or single level, I vote for full expansion.
[KMP: Sorry that you'll get this message 3 times, but I spazzed]
∂28-Mar-85 1303 @MIT-MC:HUDAK@YALE.ARPA Re: IF and WHEN
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Mar 85 13:03:04 PST
Received: from yale by MIT-MC.ARPA; 28 MAR 85 15:59:18 EST
Received: by YALE-BULLDOG.YALE.ARPA; 28 Mar 85 15:45:05 EST (Thu)
Message-Id: <8503282045.AA03847@YALE-BULLDOG.YALE.ARPA>
Received: from YALE-RING by YALE-RES via CHAOS; Thu, 28 Mar 85 15:07:00 EST
Subject: Re: IF and WHEN
Date: Thu, 28 Mar 85 15:07:03 EST
From: Paul Hudak <Hudak@YALE.ARPA>
To: Bill Rozas <JINX%MIT-OZ@MIT-MC>
Cc: scheme@MIT-MC
In-Reply-To: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>, 28 Mar 1985 10:52 EST (Thu)
Do you use EMACS?
No. Perhaps I should, but I work on an Apollo.
It occurred to me after sending the message that counting clauses
in an IF is no different than counting them in any other special form,
including bodies of LET, etc. Somehow it always seems worse for an
IF, though, perhaps because people tend to write one-liners using IF.
BTW, where does JINX%MIT-OZ@MIT-MC come from? And how does it relate
to JINX@OZ.MIT which used to work but got rejected on my last message?
Is SCHEME@MIT-MC the only relevant mailing-list for these discussions?
-Paul
∂28-Mar-85 1437 @MIT-MC:linus!ramsdell@mitre-bedford Other names for ITERATE
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Mar 85 14:37:39 PST
Received: from mitre-bedford by MIT-MC.ARPA; 28 MAR 85 17:37:56 EST
Date: 28 Mar 1985 17:36:55-EST
From: linus!ramsdell@Mitre-Bedford
Received: by linus.UUCP (4.12/4.7)
id AA06997; Thu, 28 Mar 85 09:27:45 est
Date: Thu, 28 Mar 85 09:27:45 est
From: linus!ramsdell (John D. Ramsdell)
Message-Id: <8503281427.AA06997@linus.UUCP>
To: bccvax!scheme@mit-mc.arpa
Subject: Other names for ITERATE
Here are some synonyms for let that could be
used as replacements for ITERATE. Notice they do not
give any connotation on how the named function will be used.
ALLOW
PROVIDE
ENTITLE
FOSTER
I think the following does looks pretty good.
(ALLOW LOOP ((L L) (SUM 0))
(IF (NULL? L)
SUM
(LOOP (CDR L) (+ (CAR L) SUM))))
John
∂28-Mar-85 1511 @MIT-MC:JINX@MIT-OZ Other names for ITERATE
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Mar 85 15:10:55 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 28 MAR 85 18:11:14 EST
Date: 28 Mar 1985 18:10 EST (Thu)
Message-ID: <JINX.12098722943.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: linus!ramsdell@MITRE-BEDFORD.ARPA, scheme@MIT-MC.ARPA
Subject: Other names for ITERATE
In-reply-to: Msg of 28 Mar 1985 17:36-EST
Thu 28 Mar 85 09:27:45 est from linus!ramsdell at Mitre-Bedford,
linus!ramsdell (John D. Ramsdell) at Mitre-Bedford
Why are you not willing to go one step further and notice ALLOW = LET?
∂28-Mar-85 2248 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Re: flames!
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Mar 85 22:48:48 PST
Received: from csnet-relay by MIT-MC.ARPA; 29 MAR 85 01:49:09 EST
Received: from unc by csnet-relay.csnet id a002999; 29 Mar 85 1:39 EST
Received: by unc (4.12/4.7) id AA03857; Thu, 28 Mar 85 09:35:09 est
Date: Thu, 28 Mar 85 09:35:09 est
From: Kent Dybvig <dyb%unc.csnet@csnet-relay.arpa>
Message-Id: <8503281435.AA03857@unc>
To: GJS%MIT-OZ@mit-mc.ARPA, scheme@mit-mc.ARPA
Subject: Re: flames!
(if (if p q) r s)
Could of course be written:
(if (if p q #!true) r s)
"unless" is a handy special form, in addition to "when":
(unless (zero? x) (set! x (/ 1 x)))
would have to be written as:
(when (not (zero? x)) (set! x (/ 1 x)))
or (shudder):
(if (not (zero? x)) (set! x (/ 1 x)))
It has always bothered me that the "else" part was optional
in the one-or-two-armed-if. Why can't the "then" part be
optional as well?
"when" and "unless" are clean, simple, and unambiguous. They
should both be included in the standard.
∂29-Mar-85 0713 @MIT-MC:cth%indiana.csnet@csnet-relay.arpa ITERATE, DEFINE and CELLs
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 29 Mar 85 07:13:31 PST
Received: from csnet-relay by MIT-MC.ARPA; 29 MAR 85 10:13:30 EST
Received: from indiana by csnet-relay.csnet id aa05046; 29 Mar 85 10:05 EST
Date: Fri, 29 Mar 85 08:49:59 est
From: Chris Haynes <cth%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA00974; Fri, 29 Mar 85 08:49:59 est
To: scheme@mit-mc.ARPA
Subject: ITERATE, DEFINE and CELLs
> RECURSE has the same bug that ITERATE has. The name implies a
> certain behaviour which the process it develops may not conform to. In
> particular, I usually use named let for loops, but I also use it for
> recursive procedures. The advantage of named let is that its name has
> no connotations, and that it reduces the number of "reserved"
> keywords.
Recursion subsumes iteration, so RECURSE is a good name even if used for
simple iteration, but ITERATE isn't a good name when its use is not
tail-recursive. The *disadvantage* of named let is that its name *does* have
connotation, namely local binding and *not* recursion. Our desire to keep
down the number of keywords should not be at the expense of such confusion.
> How am I supposed to define things if both DEFINE! and DEFINE
> go away?
With SET!, provided one assumes that all identifiers are initially bound in
the global environment, or that SET! can extend the global environment.
With the exception of MIT's Scheme, this is what existing systems do. If MIT
is unwilling to change this, then we are reluctantly stuck with DEFINE.
> While I agree that CELLs are nice, why are they neccesary?
> They can easily be emulated with pairs, and any implementation which
> really uses them can support them optionally.
They take up half as much space as pairs, and have many fundamental uses.
They aren't *absolutely* necessary, but then neither is most of Scheme.
Chris
Dan
∂29-Mar-85 0759 @MIT-MC:dyb%unc.csnet@csnet-relay.arpa Re: Other names for ITERATE
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 29 Mar 85 07:59:26 PST
Received: from csnet-relay by MIT-MC.ARPA; 29 MAR 85 10:59:38 EST
Received: from unc by csnet-relay.csnet id a005294; 29 Mar 85 10:52 EST
Received: by unc (4.12/4.7)
id AA07930; Fri, 29 Mar 85 09:08:20 est
Date: Fri, 29 Mar 85 09:08:20 est
From: Kent Dybvig <dyb%unc.csnet@csnet-relay.arpa>
Message-Id: <8503291408.AA07930@unc>
To: scheme@mit-mc.ARPA
Subject: Re: Other names for ITERATE
How about "spiral" or "cycle"?
Spirals can loop back on themselves, or build up in a recursive
fashion, and the name has no other connotation that I know of.
last I heard, spiral was a word in the English language (though
cdr, ref, cond and cons are not).
Cycle is also a word but may have other connotations.
(spiral f ((x l)) (if (null? l) '() (cons (car l) (f (cdr l)))))
(cycle f ((x l)) (if (null? l) '() (cons (car l) (f (cdr l)))))
∂29-Mar-85 0851 @MIT-MC:GJS@MIT-OZ WHEN, UNLESS, RECURSE, et. al.
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 29 Mar 85 08:51:08 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 29 MAR 85 11:49:46 EST
Date: Fri, 29 Mar 1985 11:47 EST
Message-ID: <GJS.12098915510.BABYL@MIT-OZ>
From: GJS%MIT-OZ@MIT-MC.ARPA
To: scheme@MIT-MC
Subject: WHEN, UNLESS, RECURSE, et. al.
Rules for Scheme standards:
(1) Entities should not be multiplied beyond necessity. -- William of Occam
(2) Special forms should not be multiplied beyond necessity.
(3) Rules for Scheme standard should not be multiplied beyond necessity.
∂29-Mar-85 0949 @MIT-MC:JINX@MIT-OZ ITERATE, DEFINE and CELLs
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 29 Mar 85 09:49:19 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 29 MAR 85 12:49:40 EST
Date: 29 Mar 1985 12:49 EST (Fri)
Message-ID: <JINX.12098926678.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Chris Haynes <cth%indiana.csnet@CSNET-RELAY.ARPA>
Cc: scheme@MIT-MC.ARPA
Subject: ITERATE, DEFINE and CELLs
In-reply-to: Msg of 29 Mar 1985 08:49-EST from Chris Haynes <cth%indiana.csnet at csnet-relay.arpa>
> Recursion subsumes iteration, so RECURSE is a good name even if used for
> simple iteration, but ITERATE isn't a good name when its use is not
> tail-recursive. The *disadvantage* of named let is that its name *does* have
> connotation, namely local binding and *not* recursion. Our desire to keep
> down the number of keywords should not be at the expense of such confusion.
I disagree. Recursion for me (and most of the MIT-Scheme people) is a
property of a process, not a feature of the particular syntax with
which it was expressed. If forms like DO loops are allowed, there is
no syntactic recursion and no real recursion. One can easily imagine
some dual special form which avoids syntactic recursion while
developing a recursive process when evaluated (executed). RECURSE
(recur) has too many such connotations for me since I view a procedure
as a way of encapsulating a process, and the only interesting thing is
the process, not its syntactic description. This distinction between
procedure and process developed by it is very important, though
irrelevant in most programming languages (without a notion of
reduction vs. subproblem) but not in Scheme. It is further expounded
in "Structure and Interpretation ..." section 1.2.1.
> With SET!, provided one assumes that all identifiers are initially bound in
> the global environment, or that SET! can extend the global environment.
> With the exception of MIT's Scheme, this is what existing systems do. If MIT
> is unwilling to change this, then we are reluctantly stuck with DEFINE.
SET! has too many connotations of side effects and I'm not willing
to acceptit as the primary definition mechanism.
I don't view definition as a side effect. Its interactive
implementation involves one, in the same way that the interpreted
implementation of LETREC involve side effects, only because we don't
know how to do it any better. The side effects do not exist for
internal definitions. In the same way that the implementation of
LETREC is incomplete (it can only find a fixed point in some cases,
not all, and the others are disallowed or give an error), the
implementation of DEFINE is incomplete. Its limitations are no worse
than the limitations of LETREC, yet they meet considerable opposition,
which I don't understand.
Purists in MIT-Scheme advocate for DEFINE to signal an error when
attempting to redefine an already existing identifier in a given
environment. While conceptually this would be not only appropriate
but logical, it has problems in an interactive system when people want
to re-load some code after making some changes to it. It would be
very cumbersome to have to change all DEFINEs into SET!s (though I
sometimes think this should be the case). This is the only reason why
we allow "re-definition" of identifiers (again interactive
constraints).
In a given program there should be no redefinitions (I believe that
our "compiler" will complain, but I'm not sure since I never do it),
and definition should occur before assignment or use. We even have a
stylistic convention (unfortunately not rigidly adhered to) to aid the
user in determining whether the definition is static (the value will
not change), or we are only introducing an identifier for further
assignment. In the latter case no initial value is given, thus
(define foo)
(set! foo 3) ; Initial value for foo, which will change
Means something quite different from
(define foo 3) ; Foo is supposed to be 3
This corresponds to LSET and DEFINE in T, but not imposed by the
system.
As you can see, in neither case does the definition conceptually
involve a side-effect, since in the second it declares a constant, and
in the first it declares an identifier which can be used in
assignments. DEFINE is thus purely declarative, as opposed to SET!
which is imperative. I believe this distinction is very important,
and justifies the keeping of DEFINE (or some such declarative form).
> They take up half as much space as pairs, and have many fundamental uses.
> They aren't *absolutely* necessary, but then neither is most of
Scheme.
I'm willing to accept them in the standard as long as the CELL type
is not required to be disjoint from PAIR (in the same way that
CHARACTER is not required to be disjoint from STRING or INTEGER).
There is actually a reason for this, I can see a few proposed memory
(debugging) utility programs whose implementation depends on the fact
that all pointer objects have at least 2 words of storage, which would
not be the case for CELLS.
If they are addopted I suggest the following names:
(MAKE-CELL VALUE) returns a CELL object with initial content VALUE.
(CELL-CONTENT CELL) returns the content of cell CELL.
(SET-CELL-CONTENT! CELL NEW-VALUE) makes the new content of CELL be
NEW-VALUE.
∂29-Mar-85 0957 @MIT-MC:JINX@MIT-OZ WHEN, UNLESS, RECURSE, et. al.
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 29 Mar 85 09:56:56 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 29 MAR 85 12:57:18 EST
Date: 29 Mar 1985 12:56 EST (Fri)
Message-ID: <JINX.12098928030.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: GJS%MIT-OZ@MIT-MC.ARPA
Cc: scheme@MIT-MC
Subject: WHEN, UNLESS, RECURSE, et. al.
In-reply-to: Msg of 29 Mar 1985 11:47-EST from GJS
(4) Messages about WHEN, UNLESS, RECURSE, etc should not be multiplied
beyond necessity.
∂29-Mar-85 1214 JAR@MIT-MC ITERATE, DEFINE, WHEN, cells, etc.
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 29 Mar 85 12:13:53 PST
Date: 29 March 1985 14:09-EST
From: Jonathan A Rees <JAR @ MIT-MC>
Subject: ITERATE, DEFINE, WHEN, cells, etc.
To: SCHEME @ MIT-MC
In-reply-to: Msg of Fri 29 Mar 85 08:49:59 est from Chris Haynes <cth%indiana.csnet at csnet-relay.arpa>
Why are people so hot to change the report? Many of these questions
(such as that of ITERATE and its alternatives) were discussed last fall,
and we agreed that we couldn't agree, so the features got omitted. The
report seems mostly fine to me, and given how strongly people feel about
iteration primitives, DEFINE, and everything else, I don't think it's
worth rocking the boat again. Perhaps not everyone who is participating
in current discussions has an understanding of how strong the
disagreements are, or perhaps they forget that we agreed that
controversial features are to be ommitted, unless their absence gravely
compromises the ability to express programs at all.
If anything, the report should be pruned, not expanded. It is already
much larger than most of us would like it to be. My suggestion that
(IF A B) be changed from essential to optional was an attempt to remove
something I thought was both redundant and controversial, and I thought
it a reasonable suggestion, for symmetry with the optionality of
(DEFINE (F X) Y) ; the fact that there's been so much argument just
supports my proposal that it be removed from the essential dialect! In
any case, I think we should concern ourselves with inconsistencies and
redundancies, not with questions which were settled (by agreeing to not
settle them) long ago. The most serious omissions (numbers, strings,
and I/O) have already been addressed. These other features are simply
not in that class (although I suppose that this meta-point is what the
arguments are about, in part).
Please, be conservative, and consider that if you are likely to meet
implacable opposition, it is probably better to be quiet. If you have a
new proposal which is just so good that you think everyone will like it,
by all means submit it, but remember that most of us are fanatical
minimalists, and have incompatible measures of minimality. Form models
of other peoples' viewpoints and modify your speeches accordingly.
Please forgive me for this outburst, but I felt things were getting a
bit out of hand. This is not to say that many recent messages have not
been reasonable and good.
Jonathan
∂29-Mar-85 1238 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa names
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 29 Mar 85 12:38:02 PST
Received: from csnet-relay by MIT-MC.ARPA; 29 MAR 85 14:41:06 EST
Received: from indiana by csnet-relay.csnet id a006294; 29 Mar 85 14:32 EST
Date: Fri, 29 Mar 85 12:02:05 est
From: Will Clinger <willc%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA03416; Fri, 29 Mar 85 12:02:05 est
To: scheme@mit-mc.ARPA
Subject: names
With respect to special forms vs procedures, IF vs IF/WHEN/UNLESS, LET vs
LET/ITERATE, and feeping creaturism, please remember that the keywords of
special forms may be reserved in some implementations and thus cannot be
used as variables in portable code. When I was a Cobol programmer, it
occurred to me that the main reason that experienced Cobol programmers were
so much more productive than inexperienced programmers was that they didn't
have to flip through the list of several hundred reserved words every time
they wanted to name a variable.
Have pity on the poor beginner. I could probably keep fifty de facto
reserved words in mind as I program, though there are more important things
that I ought to keep in mind instead. Beginners, however, are likely to
have trouble remembering the twenty or so we already have.
One of the glories of Scheme is that it gives T (and NIL) back to the
programmer. At last I can use T as a temporary or to stand for time! Now
they threaten to take away WHEN and ITERATE. Arise, programmers, and defend
your namespace!
P.S. I am in sympathy with the idea of making one-armed IF optional rather
than essential. The one-armed IF that acts like material conditional looks
like a feeping creature to me.
If our strongest disagreements have to do with procedure names, then we've
made real progress. I think MAP is much nicer than MAPCAR, and I would like
to see it adopted so we can keep up with the rest of the functional
programming community. MAPC is utterly random, but while WALK is better it
isn't obviously the right thing and it doesn't have MAPC's tradition.
Anyone for STEP, STOMP, JOG, TIPTOE, PROMENADE, TRAVERSE, or VISIT ?
William Clinger
∂29-Mar-85 1537 @MIT-MC:linus!ramsdell@mitre-bedford REC and LETREC
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 29 Mar 85 15:36:28 PST
Received: from mitre-bedford by MIT-MC.ARPA; 29 MAR 85 18:36:51 EST
Date: 29 Mar 1985 18:36:48-EST
From: linus!ramsdell@Mitre-Bedford
Received: by linus.UUCP (4.12/4.7)
id AA19046; Fri, 29 Mar 85 09:08:34 est
Date: Fri, 29 Mar 85 09:08:34 est
From: linus!ramsdell (John D. Ramsdell)
Message-Id: <8503291408.AA19046@linus.UUCP>
To: bccvax!scheme@mit-mc.arpa
Subject: REC and LETREC
An English name for REC is PROCEDURE. After all, that is
what it returns. By the way, is the predicate PROCEDURE?
missing?
Could some one explain why LETREC is preferable to LABELS?
If the name LABELS is so bad, let me suggest alternatives:
LABEL
MARK
TAG
NOTE
GIVE
SUPPLY
PROVIDE ; from the ITERATE suggestion.
ALLOW
John
∂29-Mar-85 1540 @MIT-MC:linus!ramsdell@mitre-bedford rationalized names
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 29 Mar 85 15:39:54 PST
Received: from mitre-bedford by MIT-MC.ARPA; 29 MAR 85 18:37:03 EST
Date: 29 Mar 1985 18:36:51-EST
From: linus!ramsdell@Mitre-Bedford
Received: by linus.UUCP (4.12/4.7)
id AA19092; Fri, 29 Mar 85 09:14:58 est
Date: Fri, 29 Mar 85 09:14:58 est
From: linus!ramsdell (John D. Ramsdell)
Message-Id: <8503291414.AA19092@linus.UUCP>
To: bccvax!scheme@mit-mc.arpa
Subject: rationalized names
How about adding a section on naming conventions,
much like the so named section in the T manual.
Agreeing one these conventions would greatly
increase program portability.
John
∂29-Mar-85 1545 @MIT-MC:linus!ramsdell@mitre-bedford LIST?
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 29 Mar 85 15:44:57 PST
Received: from mitre-bedford by MIT-MC.ARPA; 29 MAR 85 18:37:51 EST
Date: 29 Mar 1985 18:36:55-EST
From: linus!ramsdell@Mitre-Bedford
Received: by linus.UUCP (4.12/4.7)
id AA19122; Fri, 29 Mar 85 09:19:38 est
Date: Fri, 29 Mar 85 09:19:38 est
From: linus!ramsdell (John D. Ramsdell)
Message-Id: <8503291419.AA19122@linus.UUCP>
To: bccvax!scheme@mit-mc.arpa
Subject: LIST?
Is it agreed that LIST? should be included in the report
and that is should be defined as per Bill Rozas?
Eg. The predicate that returns true to objects generated
by LIST.
John
∂29-Mar-85 1631 @MIT-MC:mw%brandeis.csnet@csnet-relay.arpa Other names for ITERATE
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 29 Mar 85 16:31:18 PST
Received: from csnet-relay by MIT-MC.ARPA; 29 MAR 85 19:31:38 EST
Received: from brandeis by csnet-relay.csnet id ab07489; 29 Mar 85 19:17 EST
Received: by brandeis.ARPA (4.12/4.7)
id AA03530; Fri, 29 Mar 85 13:37:18 est
Date: 29 Mar 1985 13:30-EST
From: mw%brandeis.csnet@csnet-relay.arpa
In-Real-Life: Mitchell Wand,faculty
Subject: Other names for ITERATE
To: scheme@mit-mc.ARPA
Message-Id: <480969029/mw@brandeis>
How about LABEL? Except for its (obsolescent) use in Lisp and in
imperative languages, it has no other connotations, and it corresponds
nicely to the purported denotational semantics. Furthermore, each of
those uses corresponds to a recursive declaration of some sort.
Thus:
(label foo ((x 0)(y 1)(k (lambda (x) x))) blah)
BTW, "recursion" is the noun form of the verb "recur" (to occur again).
[As vision is the noun form of the verb "view"]. So if you verb
"recursion", you should get "recur", not "recurse", as in: "this
function recurs (not recurses) on the cdr of its argument."
-- Mitch
∂29-Mar-85 2135 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa NIL vs ()
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 29 Mar 85 21:35:34 PST
Received: from csnet-relay by MIT-MC.ARPA; 30 MAR 85 00:35:45 EST
Received: from ti-csl by csnet-relay.csnet id aa08681; 30 Mar 85 0:24 EST
Date: 29 Mar 1985 1355-CST
From: David Bartley <Bartley%ti-csl.csnet@csnet-relay.arpa>
Subject: NIL vs ()
To: Scheme@mit-mc.ARPA
cc: Bartley%ti-csl.csnet@csnet-relay.arpa
Received: from csl60 by ti-csl; Fri, 29 Mar 85 14:27 CST
Thanks to JAR and GJC, I have a clearer idea of how to avoid the problem
I've raised recently. This has been one of those things that could be
cleared up in 10 minutes in person, but has been beset with terminology
problems. I withdraw my request.
Regards,
David Bartley
-------
∂29-Mar-85 2138 @MIT-MC:BARTLEY%ti-csl.csnet@csnet-relay.arpa RE: The revised revised Report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 29 Mar 85 21:38:23 PST
Received: from csnet-relay by MIT-MC.ARPA; 30 MAR 85 00:35:54 EST
Received: from ti-csl by csnet-relay.csnet id ac08681; 30 Mar 85 0:24 EST
Date: 29 Mar 1985 1437-CST
From: David Bartley <Bartley%ti-csl.csnet@csnet-relay.arpa>
Subject: RE: The revised revised Report
To: Scheme@mit-mc.ARPA
cc: Bartley%ti-csl.csnet@csnet-relay.arpa
Received: from csl60 by ti-csl; Fri, 29 Mar 85 15:00 CST
Here are my votes on some of the issues swirling around the Scheme World
these days...
-- I strongly prefer the term "port."
-- I prefer the names CAR and CDR to anything else I've heard. I am
partly motivated by the desire to woo others away from inferior forms of
Lisp; avoiding such changes may help.
-- I prefer MAP and WALK to MAPCAR and MAPC. Common Lisp's MAP is a
generalization of MAPCAR, so I don't see any problem there. WALK is more
meaningful than MAPC. WALK should be optional; MAP may be either essential
or optional.
-- Both IF and WHEN are worthwhile. "One-armed" IF and WHEN should both
be optional. I use WHEN exclusively for side effects and the choice of the
name helps clarify my intent. I don't like UNLESS, because it adds nothing
new, but making it optional is OK by me.
-- I'd like to modify EQV? slightly to align it with Common Lisp's EQL.
I believe the only difference is that EQL "does the right thing" for
character data objects as well as for numbers. Does anyone oppose this?
-- I am worried about PRIMITIVE-SYNTAX-EXPAND. It "feels" like too
little, too late in the game. I'd rather allow time for this issue to gel
further.
-- It has been suggested that LAMBDA be the only special form. Unless we
tackle the subject of macros in detail, I can't imagine subcategorizing
special forms into "real" special forms and "other" special forms, some of
which may be macros.
-- I prefer named LET to ITERATE or RECURSE. ITERATE is inadequate, while
RECURSE is poor English. If we can't agree, lets make named LET and
perhaps one of the alternatives both optional (as Dan and Chris suggest).
-- Let's drop LIST?. It's both expensive and unimportant. Make it
optional if you'd like.
-- I like READ-CHAR-READY?.
-- I don't like READ-READY?. Its implementation would seem to require
buffering all of the characters going into a READ just in case we find they
don't add up to an entire parsable object. HUNG? has the same problem.
-- I agree that = and =? shouldn't both be essential. I'm willing to
switch to the '?' forms if necessary, although I prefer the others for
compatibility with the Abelson and Sussman book and with Common Lisp.
-- Let's drop #!NULL. #!FALSE and () suffice.
-- I'm willing to lose DEFINE! and DEFREC!, as Chris and Dan suggest.
-- I favor retaining NUMBER?.
-- OBJECT-HASH and OBJECT-UNHASH should be optional.
-- I prefer REF over CELL (and CELL over BOX). It should be optional. In
our work, we are also concerned about locatives and forwarding pointers, so
it isn't clear to us that REF alone is interesting.
Regards,
David Bartley
-------
∂30-Mar-85 0047 @MIT-MC:CPH@MIT-OZ ITERATE, DEFINE and CELLs
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 30 Mar 85 00:46:55 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 30 MAR 85 03:47:23 EST
Date: Sat, 30 Mar 1985 03:46 EST
Message-ID: <CPH.12099090096.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: Chris Haynes <cth%indiana.csnet@CSNET-RELAY.ARPA>
Cc: scheme@MIT-MC.ARPA
Subject: ITERATE, DEFINE and CELLs
In-reply-to: Msg of 29 Mar 1985 08:49-EST from Chris Haynes <cth%indiana.csnet at csnet-relay.arpa>
Date: Friday, 29 March 1985 08:49-EST
From: Chris Haynes <cth%indiana.csnet at csnet-relay.arpa>
> How am I supposed to define things if both DEFINE! and DEFINE
> go away?
With SET!, provided one assumes that all identifiers are initially
bound in the global environment, or that SET! can extend the
global environment. With the exception of MIT's Scheme, this is
what existing systems do. If MIT is unwilling to change this,
then we are reluctantly stuck with DEFINE.
This is a terrible idea. It seems that the ability to have many
different environments in which to perform incremental definitions has
been consistently overlooked by almost everyone except MIT Scheme and
T. Anyone who has ever tried to program a BIG system, and by that I
mean something over 500-1000 pages of code, knows that this kind of
packaging is **ESSENTIAL**!! So please don't try to take this away.
∂30-Mar-85 0054 @MIT-MC:CPH@MIT-OZ The revised revised Report
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 30 Mar 85 00:53:52 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 30 MAR 85 03:54:03 EST
Date: Sat, 30 Mar 1985 03:53 EST
Message-ID: <CPH.12099091315.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Cc: Scheme@MIT-MC.ARPA
Subject: The revised revised Report
In-reply-to: Msg of 29 Mar 1985 15:37-EST from David Bartley <Bartley%ti-csl.csnet at csnet-relay.arpa>
Regarding your most recent set of (about 15) suggestions: I agree
completely with every single one of them. Thank you.
∂31-Mar-85 1822 JAR@MIT-MC REC and LETREC
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 31 Mar 85 18:22:26 PST
Date: 31 March 1985 21:22-EST
From: Jonathan A Rees <JAR @ MIT-MC>
Subject: REC and LETREC
To: JDR @ MIT-MC
cc: SCHEME @ MIT-MC
Date: 29 Mar 1985 18:36:48-EST
From: linus!ramsdell at Mitre-Bedford
By the way, is the predicate PROCEDURE? missing?
It is intentionally missing; the decision to omit it was the outcome of
a discussion at the workshop. As I remember, it was decided that it was
unnecessary, and certain people (me) thought it was possibly meaningless
and/or harmful.
Could some one explain why LETREC is preferable to LABELS?
It was decided that a way to introduce local recursive definitions was
absolutely necessary; DEFINE of course being out of the question, there
was a heated debate between the names LABELS and LETREC, the LABELS
people arguing for English words and respect for the 1978 Revised Report
and Common Lisp, and the LETREC people arguing for something more
descriptive and allegedly pervasive in FP literature. The LABELS camp
(me) was overwhelmed, so LETREC it is. Let us be happy there was any
agreement at all.
Jonathan
∂31-Mar-85 1834 JAR@MIT-MC READ-CHAR-READY?
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 31 Mar 85 18:34:31 PST
Date: 31 March 1985 21:34-EST
From: Jonathan A Rees <JAR @ MIT-MC>
Subject: READ-CHAR-READY?
To: SCHEME @ MIT-MC
In-reply-to: Msg of 29 Mar 1985 1437-CST from David Bartley <Bartley%ti-csl.csnet at csnet-relay.arpa>
I have a little trouble reading READ-CHAR-READY? ; it sounds like it
ought to be an imperative (read a ready character), until you get to
the question mark, and then it's hard to know what to think. How about
something that sounds like it's asking a question? Something like:
WOULD-THE-READ-CHAR-PROCEDURE-BLOCK-IF-I-CALLED-IT? only shorter.
How about INPUT-AVAILABLE? or IMMEDIATELY-READABLE? or
READABLE-WITHOUT-BLOCKING? or something like that. Does anyone else
like INPUT-AVAILABLE? ? This is what it was always supposed to be
called in Yale Scheme, except that it never got implemented.
Jonathan
∂31-Mar-85 2042 @MIT-MC:cth%indiana.csnet@csnet-relay.arpa REC and LETREC
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 31 Mar 85 20:42:29 PST
Received: from csnet-relay by MIT-MC.ARPA; 31 MAR 85 23:42:10 EST
Received: from indiana by csnet-relay.csnet id ab16620; 31 Mar 85 23:28 EST
Date: Sun, 31 Mar 85 16:22:40 est
From: Chris Haynes <cth%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA03507; Sun, 31 Mar 85 16:22:40 est
To: purdue!ihnp4!linus!ramsdell@mitre-bedf
Subject: REC and LETREC
Cc: scheme@mit-mc.ARPA
> linus!ramsdell@mitre-bedf / 11:41 pm Mar 29, 1985 ****/
>
> An English name for REC is PROCEDURE. After all, that is
> what it returns. By the way, is the predicate PROCEDURE?
> missing?
REC may not return a procedure, as in
(rec foo (cons exp (lambda () ...foo...))).
I think we agreed to omit PROCEDURE?, since it doesn't do much good to
know something is a procedure (without knowing how many args it wants,
whether it ever returns, etc.).
> Could some one explain why LETREC is preferable to LABELS?
LETREC is what it seems, a recursive variant of LET. LABELS? only
expresses that it has something to do with naming (labeling) things.
Chris
∂31-Mar-85 2045 @MIT-MC:cth%indiana.csnet@csnet-relay.arpa JINX reply on RECUR, DEFINE, ...
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 31 Mar 85 20:44:53 PST
Received: from csnet-relay by MIT-MC.ARPA; 31 MAR 85 23:42:15 EST
Received: from indiana by csnet-relay.csnet id ac16620; 31 Mar 85 23:29 EST
Date: Sun, 31 Mar 85 20:07:15 est
From: Chris Haynes <cth%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA02538; Sun, 31 Mar 85 20:07:15 est
To: scheme@mit-mc.ARPA
Subject: JINX reply on RECUR, DEFINE, ...
> Recursion for me (and most of the MIT-Scheme people) is a
> property of a process, not a feature of the particular syntax with
> which it was expressed.
We agree that the distinction between process and program is
fundamental. But RECUR (Mitch's comment that RECURSE isn't English is
well taken) is at least expressive of the program (and has the
pedagogic virtue of emphasizing that program recursion expresses both
recursion and iteration of processes). Local recursion (or iteration)
is too fundamental to be subsumed by LET, which expresses local
binding, *not* recursion (or iteration).
We like Mitch's LABEL suggestion much better than named LET, but prefer
RECUR.
> SET! has too many connotations of side effects and I'm not willing
> to accept it as the primary definition mechanism.
>
> I don't view definition as a side effect. Its interactive
> implementation involves one, in the same way that the interpreted
> implementation of LETREC involve side effects, only because we don't
> know how to do it any better...
>
> Purists in MIT-Scheme advocate for DEFINE to signal an error when
> attempting to redefine an already existing identifier in a given
> environment...
Your thorough justification of MIT's rationale is appreciated. If
DEFINE could not be used to redefine existing bindings, we would have no
problem with it. If the standard said that some systems may not permit
such redefinitions, we'd feel better about DEFINE being essential.
(Though most systems would allow redefinitions to ease reloading, as
you indicated.)
Your analogy with LETREC is not as close as you make it seem, for all
code within the scope of a LETREC is known at compile time, and the
same is not true for top level bindings. (This is also the root of the
problem we have with the use of DEFINE as a substitute for LETREC.)
LETREC bindings are always new, never mutations of existing bindings.
> I'm willing to accept them in the standard as long as the CELL type
> is not required to be disjoint from PAIR (in the same way that
> CHARACTER is not required to be disjoint from STRING or INTEGER)...
>
> If they are adopted I suggest the following names:
>
> (MAKE-CELL VALUE) returns a CELL object with initial content VALUE.
>
> (CELL-CONTENT CELL) returns the content of cell CELL.
>
> (SET-CELL-CONTENT! CELL NEW-VALUE) makes the new content of CELL be
> NEW-VALUE.
We don't mind lack of disjointness. The names you propose are better
than none at all, but not our favorites (here we go again...); we use
them a lot (sometimes more than explicit cons cells) and would like
shorter names. BOX and REF have the advantage that UNBOX and DEREF
make sense, and SET-{CELL|BOX|REF}! is enough for mutation. We don't
have to say CONS-CONTENT, or SET-CONS-CONTENT!.
We know everyone has had about enough of these name debates, but they have
served the useful purpose of clarifying our rationales. We appreciate
Johnathan's restatement of the principle that if we can not agree after
making our rationales clear, then the standard should try to avoid
mentioning the points of contention. This indicates that neither named
LET nor RECUR be mentioned. DEFINE could stay, since that seems to be
the concensus, but it would be nice if its redefinition capability were
optional.
Chris
Dan
∂31-Mar-85 2047 @MIT-MC:cth%indiana.csnet@csnet-relay.arpa CPH reply on DEFINE
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 31 Mar 85 20:47:28 PST
Received: from csnet-relay by MIT-MC.ARPA; 31 MAR 85 23:42:19 EST
Received: from indiana by csnet-relay.csnet id ad16620; 31 Mar 85 23:29 EST
Date: Sun, 31 Mar 85 20:08:00 est
From: Chris Haynes <cth%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA02544; Sun, 31 Mar 85 20:08:00 est
To: scheme@mit-mc.ARPA
Subject: CPH reply on DEFINE
> CPH%MIT-OZ@MIT-MC.ARPA / 9:33 am Mar 30, 1985 ****/
>
> It seems that the ability to have many
> different environments in which to perform incremental definitions has
> been consistently overlooked by almost everyone except MIT Scheme and
> T. Anyone who has ever tried to program a BIG system, and by that I
> mean something over 500-1000 pages of code, knows that this kind of
> packaging is **ESSENTIAL**!! So please don't try to take this away.
We grant the importance of such a facility, and are not trying to take it
way; but there is no concensus on how to provide such a facility, so it
is too soon to standardize on one. (Similarly, syntactic extensions
are **ESSENTIAL** to the kind of thing we do here; but it is also too soon
to standardize on a syntactic extension mechanism.)
We were simply debating whether SET! should be required to extend the
global environment if its identifier is unbound (or equivalently, have
everything bound in the global environment to begin with). This would
make DEFINE unessential, though it might still be optional. It has
nothing to do with multiple environments for incremental definition,
except that MIT uses DEFINE for both purposes.
Chris
Dan
∂01-Apr-85 2047 JAR@MIT-MC CPH reply on DEFINE
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 1 Apr 85 20:47:02 PST
Date: 1 April 1985 23:46-EST
From: Jonathan A Rees <JAR @ MIT-MC>
Subject: CPH reply on DEFINE
To: cth%indiana.csnet @ CSNET-RELAY
cc: SCHEME @ MIT-MC
In-reply-to: Msg of Sun 31 Mar 85 20:08:00 est from Chris Haynes <cth%indiana.csnet at csnet-relay.arpa>
Date: Sun, 31 Mar 85 20:08:00 est
From: Chris Haynes <cth%indiana.csnet at csnet-relay.arpa>
We were simply debating whether SET! should be required to extend the
global environment if its identifier is unbound (or equivalently, have
everything bound in the global environment to begin with). This would
make DEFINE unessential, though it might still be optional. It has
nothing to do with multiple environments for incremental definition,
except that MIT uses DEFINE for both purposes.
I think that people at MIT and at Yale generally believe that SET!
should NOT cause the variable assigned to become bound in ANY
environment (global or otherwise) if it wasn't already. Although MIT
Scheme's idea of environments argues for this position, there are these
other reasons: (1) taste - who wants to see all those side-effects all
over the place?; (2) one form one function - DEFINE binds, SET!
updates.
While I appreciate your desire to simplify things, DEFINE and SET! are
viewed here as two totally different operations, so I think they should
remain separate & required, as we agreed last fall.
Jonathan
∂02-Apr-85 0005 @MIT-MC:CPH@MIT-OZ CPH reply on DEFINE
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 2 Apr 85 00:05:44 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 2 APR 85 03:05:44 EST
Date: Tue, 2 Apr 1985 03:05 EST
Message-ID: <CPH.12099869022.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: Chris Haynes <cth%indiana.csnet@CSNET-RELAY.ARPA>
Cc: scheme@MIT-MC.ARPA
Subject: CPH reply on DEFINE
In-reply-to: Msg of 31 Mar 1985 20:08-EST from Chris Haynes <cth%indiana.csnet at csnet-relay.arpa>
My apologies for the rather careless wording of my earlier message.
What I wanted to say was: if SET! extends the "global" environment,
then that environment has become special in that it is the ONLY
environment that can be extended by interactive definition. This
would seem to preclude the existence of many such environments.
DEFINE eliminates the problem, because it specifies, very precisely,
the environment in which the name is bound.
∂09-Apr-85 0637 @MIT-MC:wagle%indiana.csnet@csnet-relay.arpa First Class Environments and Their Extenders
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 9 Apr 85 06:36:58 PST
Received: from csnet-relay by MIT-MC.ARPA; 9 APR 85 09:37:06 EST
Received: from indiana by csnet-relay.csnet id a001256; 9 Apr 85 9:36 EST
Date: Tue, 9 Apr 85 02:35:36 est
From: Perry Wagle <wagle%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA15319; Tue, 9 Apr 85 02:35:36 est
To: scheme%indiana.csnet@csnet-relay.arpa
Subject: First Class Environments and Their Extenders
My ATN (Augmented Transition Network) is a macro that makes a grammar into
an object. This object (currently) is a closure taking one argument that is
evaluated in an environment where each state has been transformed into a
function of (currently) five arguments using letrec. Roughly:
(define-atn my-atn state2 (state1 arc1 arc2) (state2 arc3 arc4))
is transformed to:
(letrec ((state1 (lambda (...) (nexus arc1 arc2)))
(state2 (lambda (...) (nexus arc3 arc4))) )
(define! my-atn
(lambda (*sentence*) (state2 ...))))
where the "..." means "fill in the blank". NEXUS is a macro that determines
the evaluation order of the arcs (depth-first, breadth-first, parallel, etc).
One problem with this is that if I have a large ATN (with say 100 states,
and an average branching factor of 5), the compile can take a significant
amount of time, even if I have a VAX 780 all to myself at 3AM.
How do you debug the grammar. Well, first you find the state in which it
failed, you modify the source code of the grammar, and then you recompile
the ENTIRE GRAMMAR. Yuck!
The standard solution to this in the literature of ATNs (and AI in
general) seems to be to define each state as a global-binding, and not to
worry about trying to package them all up in objects. I don't like this
because its not modular -- the inards of each compiled atn-grammar is
sprawled out everywhere. I have several different atn-grammars, and I
don't want to worry about them interfering with one another.
The letrec method is a nice method, and I would like to make it work.
My current view of what I think I want is this: That letrec in the
right-hand-side of the transformation at the beginning of this note defined
a new rib (MY←RIB) in front of the "current" environment (OLDENV) creating a
new environment (MY←ENV). I want to rebind variables in MY←RIB to
expressions EVALuated in MY←ENV, and I want to extend MY←RIB with new
variables bound to the evaluations of expressions EVALuated in MY←ENV (with
MY←ENV already extended by the new variable (which is initially bound to
something like '#!unspecified', then rebound to the new value -- that is,
normal letrec semantics). I could then create functions (macros?) like
'editstate', 'addstate', 'trace-state', 'untrace-state', etc. that would do
the obvious things to a particular compiled-atn-grammar. This way, I only
have to recompile the state, not the entire grammar.
Put another way, I can modify the grammar interactively rather than in
batch mode like I am now.
PS -- I designed it this way, because I heard that first class environments
were on their way, and I thought it would eventually work the way I wanted
it too. But apparently now, the idea is that you should ONLY be able to
extend the LAST rib in the rib sequence. Seeing as how I want to extend the
second to the last rib (and two is an arbitrary number), and there being a
number of programming technique reasons for putting new ribs between me and
the second to the last rib, I have to object and call for a facility
something like 'call-with-current-rib-set!' (where set! is rebind
and extend as one), and I need to EVAL (compile, execute) in the proper
environment, MY←ENV, which is not necessarily equal to the current one, and
is procured with something like 'call-with-current-environment'.
'call/c←rib' is not necessarily incompatable with 'call/c←env' (as I almost
thought) as I can:
(let ((MY←RIB (call/c←rib (lambda (x) x)))
(MY←ENV (call/c←env (lambda (x) x))) )
(some function of MY←RIB and MY←ENV here) )
As long as I can grab a rib extender, and EVAL in a environment other than
the current one, everything is fine. The call/c←rib and call/c←env is just
illustration.
As I think that this generalizes to objects (modules), I don't think calls
to rewrite my ATN are in order unless they make the same generalization.
∂10-Apr-85 0107 @MIT-MC:CPH@MIT-OZ First Class Environments and Their Extenders
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 10 Apr 85 01:06:32 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 10 APR 85 04:06:27 EST
Date: Wed, 10 Apr 1985 04:07 EST
Message-ID: <CPH.12101977358.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: Perry Wagle <wagle%indiana.csnet@CSNET-RELAY.ARPA>
Cc: Scheme@MIT-MC
Subject: First Class Environments and Their Extenders
In-reply-to: Msg of 9 Apr 1985 02:35-EST from Perry Wagle <wagle%indiana.csnet at csnet-relay.arpa>
Why did your message get sent to this mailing list? I think that
there must have been some mistake as it seems to be inappropriate to
the purpose of the mailing list, which is a forum for the Scheme
report proposal.
∂21-Apr-85 0652 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa if, mapcar, mapc, ...
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Apr 85 06:51:52 PST
Received: from csnet-relay by MIT-MC.ARPA; 21 APR 85 09:52:11 EST
Received: from indiana by csnet-relay.csnet id a026012; 21 Apr 85 9:54 EST
Date: Sat, 20 Apr 85 15:28:35 est
From: Will Clinger <willc%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA04262; Sat, 20 Apr 85 15:28:35 est
To: scheme@mit-mc.ARPA
Subject: if, mapcar, mapc, ...
This note proposes a few significant changes and corrections to
the draft of the "Revised Revised Report". Let me know if I have
misread the consensus.
I am moving to Oregon in two weeks. I expect June will arrive
before I have finished typesetting this thing.
William Clinger
----------------------------------------------------------------
Following the Algol 60 report, I propose that all attendees at
the Brandeis workshop be listed as authors. The acknowledgements
will list other participants in the discussion over the network,
and I will sign an editor's note accepting blame for errors in
transcription and interpretation.
Chris Hanson's revised report on strings will be incorporated.
In resonse to a few complaints, I would like to replace the last
paragraph in Section I.0 ("Brief history of Scheme") with:
Scheme shares with Common Lisp [\ref] the goal of a core
language common to several implementations. Scheme differs
from Common Lisp in its emphasis upon simplicity and
function over compatibility with older dialects of Lisp.
To allow for less error checking in compiled code, in the
discussion of variable references in section II.1 "An error is
signalled if {\it variable} is unbound" should read "It is an
error if {\it variable} is unbound".
Two-armed if will change from essential to optional status.
In the discussion of cond, "The special keyword {\tt else} may be
used..." should read "The keyword or variable {\tt else} may be
used...".
define! and defrec! will be flushed altogether.
The rationale for set! will be flushed.
In the header line for backquote, "macro special form" should be
"special form".
The initial value for nil (if it is provided at all) should be
#!null rather than #!false.
Several people have asked that append! not be allowed to side
effect its last argument, so unless there is opposition that
change will be made.
See my separate note for the proposed lexical syntax of numbers
and some questions that I have concerning numbers.
There is a problem with object-hash and object-unhash. People
might want to ask themselves whether object-unhash is really useful.
The following scenario will be added to the rationale:
>>>(define x (cons 0 0))
x
>>>(object-hash x)
77
>>>(set! x 0)
...
>>>(gc) ; garbage collection occurs for some reason
...
>>>(object-unhash 77)
??? ; ill-defined: #!false or (0 . 0)
The name of mapcar will be changed to map. (There seems to be a
fair consensus for this.)
The name of mapc will be changed to for-each. (There seems to be
a fair consensus that it should be changed, and for-each seems to
me to be the best name that has been proposed. At any rate it is
the only name that has been proposed that has not drawn
objections.)
call-with-current-continuation is essential. That it was not so
indicated in the draft was a gross blunder.
The introductory material for call-with-current-continuation will
be moved to the rationale. The last sentence of the rationale,
which begins "Some people think...", will be changed to read
"Although the name is descriptive, some people feel it is too
long and have taken to calling the procedure call/cc".
The original explanation of call-with-input-file and
call-with-output-file allows the port to be closed on any throw.
This makes it impossible to use escape procedures in a portable
manner. The sentence beginning "If the current continuation ever
changes in such a way as to make it doubtful that the procedure
will return..." will therefore change to "The implementation must
not close the port unless it can prove that the port will never
again be used for a read or write operation."
eof? will be renamed eof-object?
listen? will be renamed char-ready?. (Everyone agreed that the
name should be changed, but there was little agreement on the new
name. No one seemed to care very much either.) It will be
required that if char-ready? returns #!true, then the next
read-char operation on the port must not hang, and it will be
pointed out that this has implications for the way that rubout
handlers are written.
It will be required that the load procedure does not affect the
values returned by current-input-port and current-output-port.
There are many small improvements and corrections to be made
also, but I won't bore you with them. (The above should
suffice.)
∂21-Apr-85 0654 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa lexical syntax for numbers
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Apr 85 06:54:22 PST
Received: from csnet-relay by MIT-MC.ARPA; 21 APR 85 09:52:17 EST
Received: from indiana by csnet-relay.csnet id aa26012; 21 Apr 85 9:54 EST
Date: Sat, 20 Apr 85 15:33:46 est
From: Will Clinger <willc%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA04306; Sat, 20 Apr 85 15:33:46 est
To: scheme@mit-mc.ARPA
Subject: lexical syntax for numbers
A proposed lexical syntax for Scheme numbers.
The draft of the Revised Revised Report did not specify a lexical
syntax for numbers. This proposal is consistent with the draft
but it incorporates a large number of rather arbitrary decisions
that are likely to be controversial. Feel free to controverse.
Actually there are two proposals. The first proposal is for full
(optional) Scheme and the second is for essential Scheme.
(Implementations would be free to implement anything in between
or to extend the syntax so long as the extended syntax didn't
conflict with the optional syntax, right?)
x* means zero or more occurrences of x.
Spaces never appear inside a number, so all spaces in the syntax
are for legibility.
<empty> is the empty string.
bit --> 0 | 1
oct --> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
dit --> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
hit --> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
| a | b | c | d | e | f
| A | B | C | D | E | F
radix2 --> #b | #B
radix8 --> #o | #O
radix10 --> <empty> | #d | #D
radix16 --> #h | #H
exactness --> <empty> | #i | #I | #e | #E
precision --> <empty> | #s | #S | #l | #L
prefix2 --> radix2 exactness precision | radix2 precision exactness
| exactness radix2 precision | exactness precision radix2
| precision radix2 exactness | precision exactness radix2
prefix8 --> radix8 exactness precision | radix8 precision exactness
| exactness radix8 precision | exactness precision radix8
| precision radix8 exactness | precision exactness radix8
prefix10 --> radix10 exactness precision | radix10 precision exactness
| exactness radix10 precision | exactness precision radix10
| precision radix10 exactness | precision exactness radix10
prefix16 --> radix16 exactness precision | radix16 precision exactness
| exactness radix16 precision | exactness precision radix16
| precision radix16 exactness | precision exactness radix16
sign --> <empty> | + | -
suffix --> <empty> | e d d* | E d d* | e - d d* | E - d d*
ureal --> prefix2 bit bit* #* suffix
| prefix2 bit bit* #* / bit bit* #* suffix
| prefix2 . bit bit* #* suffix
| prefix2 bit bit* . bit* #* suffix
| prefix2 bit bit* #* . #* suffix
| prefix8 oct oct* #* suffix
| prefix8 oct oct* #* / oct oct* #* suffix
| prefix8 . oct oct* #* suffix
| prefix8 oct oct* . oct* #* suffix
| prefix8 oct oct* #* . #* suffix
| prefix10 dit dit* #* suffix
| prefix10 dit dit* #* / dit dit* #* suffix
| prefix10 . dit dit* #* suffix
| prefix10 dit dit* . dit* #* suffix
| prefix10 dit dit* #* . #* suffix
| prefix16 hit hit* #* suffix
| prefix16 hit hit* #* / hit hit* #* suffix
| prefix16 . hit hit* #* suffix
| prefix16 hit hit* . hit* #* suffix
| prefix16 hit hit* #* . #* suffix
real --> sign ureal
number --> real | real + ureal i | real - ureal i | real @ real
Some consequences of this syntax are reported below. Please keep
in mind that when I say a syntax is "illegal", I mean that it is
not generated by the syntax above and is therefore not a number
in (full optional) Scheme. The syntax could represent a legal
symbol or even a legal number in an extended Scheme.
Consequences:
Exponents are always in base 10.
Exponents may not have explicit + signs.
e+4 is illegal
1E+3 is illegal
#d+3 is illegal
4-+5i is illegal
4#.5 is illegal
#d5/#o10 is illegal
-4/-5 is illegal
#o5/10 is .625
#s4 is legal
#s#i#b.10##-#x#L#Ea.bi is legal
The proposal for essential Scheme:
dit --> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
sign --> <empty> | + | -
number --> sign dit dit*
Question about exactness: In an implementation that doesn't keep
track of exactness, the exact? predicate should always return
#!false. Right?
William Clinger
willc@indiana
after 1 May: willc@tektronix
∂21-Apr-85 1444 @MIT-MC:rhh@MIT-VAX reactions to Will's updates
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Apr 85 14:44:02 PST
Received: from MIT-VAX by MIT-MC via Chaosnet; 21 APR 85 17:44:14 EST
Received: by mit-vax.Mit-chaos.Arpa (4.12/4.8) id AA03260; Sun, 21 Apr 85 17:43:51 est
Date: Sun, 21 Apr 85 17:43:51 est
From: Bert Halstead <rhh@mit-vax>
To: scheme@mc
Subject: reactions to Will's updates
unhash-object sounds like a bad idea. In Will's scenario, if an object
(0 . 0) is passed to hash-object, and, say, 77 is returned, subsequent
calls to (unhash-object 77) must return either (0 . 0) or #!false
(presumably the latter is an out if the (0 . 0) has been garbage-
collected). This implies that 77 can NEVER be reused as the hash
code for some other object passed to hash-object! It also implies
(do we want this?) that hash-object is a one-to-one function -- it
is never permissible for more than one object to map to the same hash
code. This is not necessary if hash-object is just a way to compute
an index into some user-maintained hash table, where objects could
be associated with whatever information is desired.
re numbers: Is anything substantial gained by disallowing explicit
"+" signs on the exponents of numbers in scientific notation? -Bert
∂21-Apr-85 1923 @MIT-MC:JINX@MIT-OZ lexical syntax for numbers
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Apr 85 19:22:56 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 21 APR 85 22:22:06 EST
Date: 21 Apr 1985 22:20 EST (Sun)
Message-ID: <JINX.12105060042.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Will Clinger <willc%indiana.csnet@CSNET-RELAY.ARPA>
Cc: scheme@MIT-MC.ARPA
Subject: lexical syntax for numbers
In-reply-to: Msg of 20 Apr 1985 15:33-EST from Will Clinger <willc%indiana.csnet at csnet-relay.arpa>
Two comments:
Why can't exponents have + signs, and why must they be decimal? It
seems to me that they should be any valid representation of an
integer, though they may always want to be exact.
Why don't we fix the order of the exactness, radix, and precision
modifiers? I don't think anything is gained from allowing arbitrary
order and the parser may become simpler if it can easily default.
∂21-Apr-85 1927 @MIT-MC:JINX@MIT-OZ reactions to Will's updates
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Apr 85 19:27:08 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 21 APR 85 22:25:23 EST
Date: 21 Apr 1985 22:24 EST (Sun)
Message-ID: <JINX.12105060636.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Bert Halstead <rhh%MIT-VAX@MIT-MC.ARPA>
Cc: scheme@MIT-MC
Subject: reactions to Will's updates
In-reply-to: Msg of 21 Apr 1985 17:43-EST from Bert Halstead <rhh at mit-vax>
Instead of hash-object and unhash-object, why don't we include
populations? The implementation can be done in terms of hash and
unhash object or more primitively, and they seem to constitute the
most common use of these procedures.
∂21-Apr-85 1929 @MIT-MC:CPH@MIT-OZ lexical syntax for numbers
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Apr 85 19:29:47 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 21 APR 85 22:29:25 EST
Date: Sun, 21 Apr 1985 22:28 EST
Message-ID: <CPH.12105061355.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
Cc: Scheme@MIT-MC.ARPA
Subject: lexical syntax for numbers
In-reply-to: Msg of 21 Apr 1985 22:20-EST from Bill Rozas <JINX>
Date: Sunday, 21 April 1985 22:20-EST
From: Bill Rozas <JINX>
Why don't we fix the order of the exactness, radix, and precision
modifiers? I don't think anything is gained from allowing arbitrary
order and the parser may become simpler if it can easily default.
One thing that is gained from arbitrary order is that one need not
remember what the particular order is -- a great advantage to people
who don't remember trivial details very well and don't like reading
manuals.
∂21-Apr-85 1931 @MIT-MC:CPH@MIT-OZ reactions to Will's updates
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Apr 85 19:31:29 PST
Received: from MIT-OZ by MIT-MC via Chaosnet; 21 APR 85 22:31:16 EST
Date: Sun, 21 Apr 1985 22:29 EST
Message-ID: <CPH.12105061716.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
Cc: Bert Halstead <rhh%MIT-VAX@MIT-MC.ARPA>, scheme@MIT-MC
Subject: reactions to Will's updates
In-reply-to: Msg of 21 Apr 1985 22:24-EST from Bill Rozas <JINX>
Date: Sunday, 21 April 1985 22:24-EST
From: Bill Rozas <JINX>
Instead of hash-object and unhash-object, why don't we include
populations? The implementation can be done in terms of hash and
unhash object or more primitively, and they seem to constitute the
most common use of these procedures.
Actually, the major reason that we implemented hashing is to have
generalized two dimensional property tables, for generic operations.
∂22-Apr-85 1103 JAR@MIT-MC hashing
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Apr 85 11:03:43 PST
Date: Mon, 22 Apr 85 13:40:27 EST
From: Jonathan A Rees <JAR@MIT-MC>
Subject: hashing
To: rhh@MIT-VAX
cc: SCHEME@MIT-MC
In-reply-to: Msg of Sun 21 Apr 85 17:43:51 est from Bert Halstead <rhh at mit-vax>
Message-ID: <[MIT-MC].464776.850422.JAR>
Date: Sun, 21 Apr 85 17:43:51 est
From: Bert Halstead <rhh at mit-vax>
... This implies that 77 can NEVER be reused as the hash
code for some other object passed to hash-object!
This is an intentional feature of the proposal; if recycling is
permitted then the facility takes on a totally different character and
has more liimted application.
Feature:
Non-re-use means that OBJECT-UNHASH, which is desirable for many
applications of these things (like post-GC automatic file closing, weak
tables, and populations), is possible and meaningful.
Antifeatures:
(1) Non-re-use means that OBJECT-HASH is different from Maclisp MAKNUM,
and is therefore, presumably, more expensive.
(2) Non-re-use means that in very-long-lived systems, hash numbers might
go into bignums.
---
The hash/unhash facility is already optional, and I would suggest that
if for some reason you don't like its details you can just not implement
it.
If there is much disagreement now about the facility, then it should be
removed from the report. This removal should be done carefully, since
we agreed on it last fall, and agreements are precious; a different hash
facility probably won't make it into the report.
Jonathan
∂22-Apr-85 1117 JAR@MIT-MC hashing
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Apr 85 11:17:40 PST
Date: Mon, 22 Apr 85 14:12:52 EST
From: Jonathan A Rees <JAR@MIT-MC>
Subject: hashing
To: JINX@MIT-OZ
cc: SCHEME@MIT-MC, rhh@MIT-VAX
In-reply-to: Msg of 21 Apr 1985 22:24 EST (Sun) from Bill Rozas <JINX%MIT-OZ at MIT-MC.ARPA>
Message-ID: <[MIT-MC].464817.850422.JAR>
Date: 21 Apr 1985 22:24 EST (Sun)
From: Bill Rozas <JINX%MIT-OZ at MIT-MC.ARPA>
Instead of hash-object and unhash-object, why don't we include
populations? The implementation can be done in terms of hash and
unhash object or more primitively, and they seem to constitute the
most common use of these procedures.
I don't think populations are much easier to implement than hash/unhash,
and they aren't as general. T started out having populations, and a
year or two later acquired OBJECT-HASH, which was applicable in many
situations where populations wouldn't do. (I think you might be able
to implement hash/unhash in terms of populations, but it's much less
natural than vice versa.)
Uses for hash/unhash include populations, weak tables, and file closing,
as well as the following interesting hack, which has tremendous
popularity with users: PRINT calls OBJECT-HASH when it comes across an
object with no standard external representation, a procedure for
example, and prints the hash number along with any other type and
identification info it can find: e.g.
> cadr ;User's typein
#{Procedure 31 CADR} ;System's typeout
> (lambda (x) (* x 3))
#{Procedure 32}
>
Although the syntax #{...} isn't readable (that could cause very bizarre
results for READ's done in processes different from the one which
printed the object), you can evaluate (OBJECT-UNHASH 32) and, if the
garbage collector hasn't done away with it, get the procedure back.
This is vaguely like "D-lines" in Macsyma, except that it permits
reclamation.
Note that hash is called only when PRINT is called, so there is no
evaluator overhead involved. (One user was at first baffled by the
following interaction:
> (lambda () 1)
#{Procedure 33}
> (lambda () 2)
#{Procedure 34}
> (do ((i 0 (1+ i))
(p nil (lambda () i)))
((= i 100) p))
#{Procedure 35}
>
and then figured out that PRINT was generating the numbers.)
∂22-Apr-85 1226 @MIT-MC:wagle%indiana.csnet@csnet-relay.arpa mapcar and mapc
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Apr 85 12:25:45 PST
Received: from csnet-relay by MIT-MC.ARPA; 22 APR 85 15:24:22 EST
Received: from indiana by csnet-relay.csnet id a002853; 22 Apr 85 15:16 EST
Date: Mon, 22 Apr 85 13:54:19 est
From: Perry Wagle <wagle%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA17597; Mon, 22 Apr 85 13:54:19 est
To: scheme%indiana.csnet@csnet-relay.arpa
Subject: mapcar and mapc
In response to Will Clinger's acceptance of the "mapc" -> "for-each"
renaming:
How about renaming "mapc" to "mapcar!" (and thence to "map!")?
This would change the meaning of the bang notation from "Hi! I'm a
side-effecting function" to "Hi! I'm expecting either myself or one of the
functions that I call to be a side-effecting function".
This way, the two very simular functions "map" and "map!" keep simular
names, making life easier on the frail memory of the user.
Perry Wagle
∂22-Apr-85 1302 @MIT-MC:rhh@MIT-VAX Re: hashing
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Apr 85 13:02:29 PST
Received: from MIT-VAX by MIT-MC via Chaosnet; 22 APR 85 16:02:23 EST
Received: by mit-vax.Mit-chaos.Arpa (4.12/4.8) id AA08654; Mon, 22 Apr 85 16:02:07 est
Date: Mon, 22 Apr 85 16:02:07 est
From: Bert Halstead <rhh@mit-vax>
To: JAR@MIT-MC
Subject: Re: hashing
Cc: SCHEME@MIT-MC
Roger, I'm sensitive to the practical issues you raise, as to the mechanics
of getting agreement on the Scheme report. I don't object to object-hash
and object-unhash as optional Scheme functions -- I was just flaming about
implementation considerations which, if they had occurred to me during the
workshop, I had long since forgotten about. It does seem like the issues
of long-lived systems, and the cost of maintaining a hash space that is
ultimately sparsely populated, provide some food for thought. But that's
one thing that optional features are for. -b.
∂22-Apr-85 1544 @MIT-MC:linus!ramsdell@mitre-bedford Two armed IF is essential.
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Apr 85 15:44:28 PST
Received: from mitre-bedford by MIT-MC.ARPA; 22 APR 85 18:43:53 EST
Date: 22 Apr 1985 18:36:48-EST
From: linus!ramsdell@Mitre-Bedford
Received: by linus.UUCP (4.12/4.7)
id AA11664; Mon, 22 Apr 85 09:57:17 est
Date: Mon, 22 Apr 85 09:57:17 est
From: linus!ramsdell (John D. Ramsdell)
Message-Id: <8504221457.AA11664@linus.UUCP>
To: bccvax!scheme@mit-mc.arpa
Subject: Two armed IF is essential.
>>>From bccvax!willc%indiana.csnet@csnet-relay.arpa Sun Apr 21 14:30:50 1985
>>>...
>>>Two-armed if will change from essential to optional status.
One-armed IF may change from essential to optional status,
but please don't change two-armed IF.
John
∂22-Apr-85 1547 @MIT-MC:linus!ramsdell@mitre-bedford REC => LABEL
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Apr 85 15:46:59 PST
Received: from mitre-bedford by MIT-MC.ARPA; 22 APR 85 18:44:29 EST
Date: 22 Apr 1985 18:36:55-EST
From: linus!ramsdell@Mitre-Bedford
Received: by linus.UUCP (4.12/4.7)
id AA12343; Mon, 22 Apr 85 10:34:00 est
Date: Mon, 22 Apr 85 10:34:00 est
From: linus!ramsdell (John D. Ramsdell)
Message-Id: <8504221534.AA12343@linus.UUCP>
To: bccvax!scheme@mit-mc.arpa
Subject: REC => LABEL
I know its too late, but I support Mitch Wand's
suggested rename for REC.
John
∂23-Apr-85 0912 @MIT-MC:wagle%indiana.csnet@csnet-relay.arpa Retraction and Resubmission
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 23 Apr 85 09:11:58 PST
Received: from csnet-relay by MIT-MC.ARPA; 23 APR 85 11:58:20 EST
Received: from indiana by csnet-relay.csnet id ad08662; 23 Apr 85 11:52 EST
Date: Tue, 23 Apr 85 11:12:36 est
From: Perry Wagle <wagle%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA11641; Tue, 23 Apr 85 11:12:36 est
To: scheme%indiana.csnet@csnet-relay.arpa
Subject: Retraction and Resubmission
I noticed later that my suggestion about the renaming of "mapc" is
somewhat bogus, I apologize:
Mapcar-type functions have two primary operating parameters: (1) the order
in which the list is processed, (2) a resultant value from whether the list
is copied, side-effected, or forgotten.
The current "mapcar" processes in arbitrary order and returns the copied
list. The current "mapc" processes in left-to-right order and forgets the
list (returning nothing). Quite, ahem, different.
(The most direct interpretation of a function named "mapcar!" would be one
that set-car!ed the list, returned the side-effected list, and was open as
to whether to process in arbitrary or left-to-right order.)
I would have use for (in order of frequency):
(1) arb-order, copy list, return list. (the current mapcar).
(2) LR-order, copy list, return list. I don't like set-car!ing cons-cells,
but I make much use of files and continuations, so order matters a lot.
(3) LR-order, forget list, return nothing. (the current mapc). Print lists.
(4) LR-order, side-effect list, return list. If keeping same cons-cell is
important for some reason.
Perhaps only a subset of the set of useful mapcar variations should be
provided by the system - the two that already are? The points would still
remain of denoting their status as a member of this grouping by using the
word "map" in the name, of having special marking for functions that
guarantee left-to-right evaluation or processing, and having a naming
convention for the others should they ever be realized.
My suggestion is to distinguish between the arbitrary and left-to-right
list processing but starting off with two roots "map" and "map/lr",
respectively. Futhermore, since there are three values returned - a copied
list, a set-car!ed list, and nothing at all - "copy", "list!", and "" (null),
respectively. Then the four hypothetical functions above would be named:
(1) "map->copy"
(2) "map/lr->copy"
(3) "map/lr"
(4) "map/lr->list!" or "map/lr->same!" or ... (?)
(Note that while there would be no reasonable value for (a fifth) "map" to
return, while "map/lr" could return the value of the last mapping.)
Perry Wagle
∂23-Apr-85 1336 JAR@MIT-MC Two armed IF is essential.
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 23 Apr 85 13:36:20 PST
Date: Tue, 23 Apr 85 16:25:21 EST
From: Jonathan A Rees <JAR@MIT-MC>
Subject: Two armed IF is essential.
To: SCHEME@MIT-MC, linus!ramsdell@MITRE-BEDFORD
In-reply-to: Msg of 22 Apr 1985 18:36:48-EST
Mon 22 Apr 85 09:57:17 est from linus!ramsdell at Mitre-Bedford,
linus!ramsdell (John D. Ramsdell) at Mitre-Bedford
Message-ID: <[MIT-MC].466615.850423.JAR>
Date: 22 Apr 1985 18:36:48-EST
From: linus!ramsdell at Mitre-Bedford
One-armed IF may change from essential to optional status,
but please don't change two-armed IF.
I think this was what Will intended to write. The terminology is
confusing, since an IF with N arms has N+1 subforms, and he probably
wrote arm and meant subform.
So: (IF test consequent alternate) essential
(IF test consequent) optional
Jonathan
∂24-Apr-85 1541 @MIT-MC:willc%indiana.csnet@csnet-relay.arpa two-armed if (oops)
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 24 Apr 85 15:41:40 PST
Received: from csnet-relay by MIT-MC.ARPA; 24 APR 85 18:41:59 EST
Received: from indiana by csnet-relay.csnet id ad16863; 24 Apr 85 14:38 EST
Date: Wed, 24 Apr 85 12:48:17 est
From: Will Clinger <willc%indiana.csnet@csnet-relay.arpa>
Received: by iuvax.UUCP; id AA05047; Wed, 24 Apr 85 12:48:17 est
To: scheme@mit-mc.ARPA
Subject: two-armed if (oops)
Yikes! Thank you John, I meant to say that ONE-ARMED IF would become
optional. TWO-ARMED IF will remain essential, of course.
There has already been sufficient response to convince me that plus signs
should be allowed in exponents.
Still at issue is whether exponents can have radix, precision, or exactness
specifiers, and indeed whether exponents should be allowed to have arbitrary
number syntax. At some point the more general exponent syntax should become
extended rather than optional, and all we're trying to do is to determine
that point.
Peace, William
∂25-Apr-85 0902 @MIT-MC:rhh@MIT-VAX number exponent syntax
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 25 Apr 85 09:01:49 PST
Received: from MIT-VAX by MIT-MC via Chaosnet; 25 APR 85 12:03:03 EST
Received: by mit-vax.Mit-chaos.Arpa (4.12/4.8) id AA05298; Thu, 25 Apr 85 12:01:58 est
Date: Thu, 25 Apr 85 12:01:58 est
From: Bert Halstead <rhh@mit-vax>
To: scheme@mit-mc.ARPA, willc%indiana.csnet@csnet-relay.arpa
Subject: number exponent syntax
Seems to me that precision and exactness are (almost) completely
meaningless in an exponent. One could perhaps make an argument for
different radices in the exponent notation, but then one could also
make an argument for other things (e.g., scientific notation with
a base other than 10). I'd probably just as soon we didn't. -Bert
∂26-Apr-85 0037 JAR@MIT-MC number exponent syntax
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 26 Apr 85 00:36:50 PST
Date: Thu, 25 Apr 85 15:42:31 EST
From: Jonathan A Rees <JAR@MIT-MC>
Subject: number exponent syntax
To: rhh@MIT-VAX
cc: SCHEME@MIT-MC
In-reply-to: Msg of Thu 25 Apr 85 12:01:58 est from Bert Halstead <rhh at mit-vax>
Message-ID: <[MIT-MC].469882.850425.JAR>
Date: Thu, 25 Apr 85 12:01:58 est
From: Bert Halstead <rhh at mit-vax>
Seems to me that precision and exactness are (almost) completely
meaningless in an exponent. One could perhaps make an argument for
different radices in the exponent notation, but then one could also
make an argument for other things (e.g., scientific notation with
a base other than 10). I'd probably just as soon we didn't.
I'm not one to talk, since I never use numbers, but I read a CACM
article once about a proposed hardware number representation in which
one could represent numbers with no significant digits in their
EXPONENT. The author claimed that this was useful. So not all of
this meaninglessness is to be concluded forgonely.
Don't take this as a contrary argument; merely a word of caution.
Jonathan
∂26-Apr-85 0351 @MIT-MC:rhh@MIT-VAX Re: number exponent syntax
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 26 Apr 85 03:51:03 PST
Received: from MIT-VAX by MIT-MC via Chaosnet; 25 APR 85 16:08:56 EST
Received: by mit-vax.Mit-chaos.Arpa (4.12/4.8) id AA09287; Thu, 25 Apr 85 16:07:44 est
Date: Thu, 25 Apr 85 16:07:44 est
From: Bert Halstead <rhh@mit-vax>
To: JAR@MIT-MC
Subject: Re: number exponent syntax
Cc: SCHEME@mc
Yeah, I saw the same article, and it was the thought of that that caused
me to insert the words "(almost)" in my message. But once we start
having impreciseness in our exponent, there is little point to saying
anything about the mantissa! I figured this was probably a minefield
Scheme could avoid entering. -Bert
∂21-Jun-85 1631 @MIT-MC.ARPA:willc%tekchips%tektronix.csnet@csnet-relay.arpa lcm
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Jun 85 16:31:10 PDT
Received: from csnet-relay by MIT-MC.ARPA 21 Jun 85 19:31:11 EST
Received: from tektronix by csnet-relay.csnet id ac01342; 21 Jun 85 18:43 EDT
From: Will Clinger <willc%tekchips%tektronix.csnet@csnet-relay.arpa>
To: scheme@MIT-MC.ARPA
Received: from tekchips by tektronix with smtp ; 21 Jun 85 11:30:56 PDT
Date: Friday, 21 Jun 85 11:25:37 PDT
Subject: lcm
A question from John Gateley (gateley%waltz@ti-csl.csnet) and my response:
Gateley:
Common lisp says (lcm) = infinity, and since they don't have
a representation of infinity, lcm is required to have at least
one argument. Scheme says (lcm) = 1. Also, common lisp allows lcm to
take 0 as an argument, with result 0. Scheme does not allow zero as
an argument. Is this what is desired, or should scheme be closer to
common lisp.
Clinger:
The relevant passage in Guy Steele's book is on page 202:
"Mathematically, (lcm) should return infinity. Because Common Lisp
does not have a representation for infinity, lcm, unlike gcd, always
requires at least one argument."
Even as a mathematician, I can't agree that (lcm) should return infinity,
because the n-ary generalization of an associative binary operator should
return an identity for the operator when it is given no arguments. Infinity
certainly isn't an identity for lcm. 1 is.
I think I inserted the requirement that the arguments to lcm be non-zero. I
have no particular quarrel with Common Lisp on this matter, but I didn't want
to get bogged down in pathological cases. Since it is inconsistent to allow
zero as an argument to gcd but not to lcm, I would like to change the report so
that lcm behaves as in Common Lisp when given a zero argument.
∂21-Jun-85 1723 @MIT-MC.ARPA:ANDY@SU-SUSHI.ARPA Re: lcm
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Jun 85 17:23:16 PDT
Received: from SU-SUSHI.ARPA by MIT-MC.ARPA 21 Jun 85 20:22:54 EST
Date: Fri 21 Jun 85 17:22:22-PDT
From: Andy Freeman <ANDY@SU-SUSHI.ARPA>
Subject: Re: lcm
To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
cc: scheme@MIT-MC.ARPA
In-Reply-To: Message from "Will Clinger <willc%tekchips%tektronix.csnet@csnet-relay.arpa>" of Fri 21 Jun 85 16:37:59-PDT
(lcm) recently came up on the common lisp mailing list and that the
decision was that the Common Lisp manual was wrong. I believe Bill
Gosper and Alan Bawden were major participants in that discussion.
I'd review that before making a decision.
-andy
-------
∂09-Jul-85 2145 @MIT-MC.ARPA:ALTMAN%ti-csl.csnet@csnet-relay.arpa Scheme Benchmark Programs Sought
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 9 Jul 85 21:45:03 PDT
Received: from csnet-relay by MIT-MC.ARPA.ARPA; 10 Jul 85 00:39:55 EDT
Received: from ti-csl by csnet-relay.csnet id aj16083; 10 Jul 85 0:30 EDT
Date: 9 Jul 1985 0937-CDT
From: Arthur <Altman%CSL60%ti-csl.csnet@csnet-relay.arpa>
Subject: Scheme Benchmark Programs Sought
To: scheme@mit-mc.ARPA
cc: scheme.users%CSL60%ti-csl.csnet@csnet-relay.arpa
Received: from csl60 by ti-csl; Tue, 9 Jul 85 21:10 CST
Hello, Un-Common Lisp Lovers:
I am beginning a Scheme performance evaluation project here at TI CSL,
an initial task being to build a suite of benchmark programs. Beyond the
Gabriel Lisp Benchmark Suite translated to Scheme and examples from A&S,
most Scheme programs around these days seem to be "systems" code, e.g.,
compilers and editors.
I am soliciting "applications" code from Scheme users, especially
programs that show off **canonical Scheme programming style**. I am not
placing any limits a priori on the code size, however, I do request that
source provided conforms to the Revised Revised Report.
What's in it for you? Well, possible enshrinement of your name and all
or part of your favorite program in a "standard" benchmark suite for
Scheme. Also, the good feeling that comes with advancing the cause of
Lisp-Done-Right, since I hope to show off the performance advantages of
the Scheme runtime model.
The ultimate suite of programs will be made available over the net to
interested parties, of course. Thanks for your cooperation.
Regards,
Arthur Altman
Texas Instruments
Computer Science Laboratory
(214) 995-0383
CSNET: altman@ti-csl
ARPANET: altman%ti-csl@csnet-relay
U.S. Postal Service: M.S. 238, P.O. Box 226015, Dallas, Texas, 75266
-------
∂09-Jul-85 2325 @MIT-MC.ARPA:mw%brandeis.csnet@csnet-relay.arpa What cr*p
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 9 Jul 85 23:24:55 PDT
Received: from csnet-relay by MIT-MC.ARPA.ARPA; 10 Jul 85 02:26:14 EDT
Received: from brandeis by csnet-relay.csnet id a016623; 10 Jul 85 2:18 EDT
Received: by brandeis.ARPA (4.12/4.7)
id AA08833; Tue, 9 Jul 85 22:33:50 edt
Date: 9 Jul 1985 22:27-EST
From: mw%brandeis.csnet@csnet-relay.arpa
In-Real-Life: Mitchell Wand,faculty
Subject: What cr*p
To: dpf%indiana.csnet@csnet-relay.arpa,
lang-scheme%indiana.csnet@csnet-relay.arpa,
cth%indiana.csnet@csnet-relay.arpa, scheme@mit-mc.ARPA
Message-Id: <489810451/mw@brandeis>
Would you believe that Software: Practice & Experience is about to
publish a paper entitled "On the role of t and nil in Lisp", and whose
abstract is "It is widely believed that McCarthy's interpreter is a
running Lisp program. It is not, because it does not interpret t and
nil correctly. We show how to fix this bug." It's only 2-1/2 pages,
but MUMBLE!
∂11-Jul-85 2016 GJC@MIT-MC.ARPA What cr*p
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 11 Jul 85 20:16:18 PDT
Date: Thu, 11 Jul 85 23:17:53 EDT
From: George J. Carrette <GJC@MIT-MC.ARPA>
Subject: What cr*p
To: mw%brandeis.csnet@CSNET-RELAY.ARPA
cc: SCHEME@MIT-MC.ARPA, cth%indiana.csnet@CSNET-RELAY.ARPA,
dpf%indiana.csnet@CSNET-RELAY.ARPA,
lang-scheme%indiana.csnet@CSNET-RELAY.ARPA
In-reply-to: Msg of 9 Jul 1985 22:27-EST from mw%brandeis.csnet at csnet-relay.arpa
Message-ID: <[MIT-MC.ARPA].572724.850711.GJC>
If you think *thats* bad... a paper on a reference count garbage
collection technique in the ISA conference on expert systems
and robotics this June.
And if you think thats bad you should see the kind of proposals
DOD is getting for "supercomputer lispmachines"
∂19-Jul-85 1756 @MIT-MC.ARPA:linus!ramsdell@mitre-bedford CSI Lisp is not tail recursive
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 19 Jul 85 17:55:52 PDT
Received: from mitre-bedford by MIT-MC.ARPA 19 Jul 85 20:56:49 EDT
Date: 19 Jul 1985 20:51:17-EDT
From: linus!ramsdell@Mitre-Bedford
Received: by linus.UUCP (4.12/4.7)
id AA25878; Fri, 19 Jul 85 09:48:40 edt
Date: Fri, 19 Jul 85 09:48:40 edt
From: linus!ramsdell (John D. Ramsdell)
Message-Id: <8507191348.AA25878@linus.UUCP>
To: bccvax!scheme@mit-mc.arpa
Subject: CSI Lisp is not tail recursive
An advertisement for CSI Lisp recently appeared in CACM.
The ad states "CSI LISP is a new implementation of T,
which is decended from SCHEME". For those who don't know,
T is a dialect of SCHEME that is fairly true to SCHEME's
basic ideas. For example, T programmers are allowed to
assume that evaluation of programs is tail recursive.
Looping constructs generated out of tail recursive
procedures do not increase the size of the stack.
Recent mail to T-DISCUSSION@YALE reveal that CSI Lisp
makes no promise to be tail recursive and is not tail
recursive on implementations that run on top of
Common Lisp and LISP-VM! I believe Cognitive Systems
must reveal that CSI Lisp is not tail recursive or
it should not associate CSI Lisp with T and SCHEME
in its ads.
In my opinion, a language should, at the very least,
be tail recursive if it is to be associated with SCHEME.
John
PS Ada's name is protected - can anything be done for
SCHEME's name?
∂20-Jul-85 0350 GJC@MIT-MC.ARPA truth in advertisement
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 20 Jul 85 03:50:10 PDT
Date: Sat, 20 Jul 85 06:51:14 EDT
From: George J. Carrette <GJC@MIT-MC.ARPA>
Subject: truth in advertisement
To: SCHEME@MIT-MC.ARPA, linus!ramsdell@MITRE-BEDFORD.ARPA
In-reply-to: Msg of 19 Jul 1985 20:51:17-EDT
Fri 19 Jul 85 09:48:40 edt from linus!ramsdell at Mitre-Bedford,
linus!ramsdell (John D. Ramsdell) at Mitre-Bedford
Message-ID: <[MIT-MC.ARPA].582540.850720.GJC>
I think that just about all one can do is send letters to the editors
of the magazines publishing such advertisements. Another thing one can
do is write a letter to the company asking "will your product run the
enclosed program: X" to which they will probably reply yes (because it
will on one implementation). Then you write a letter saying, "great,
here is my $$$ please send me a copy." Then when you get the bogus
copy that wont run your program you say to them: "Please send my money
back." To make it most effective you get 10 or 20 people in on this
doing exactly the same thing. The company wont be as willing to give
back thousands of dollars. Then when they dont give the money back you
go to the Atterny (spell program no help for this word) General's
Office and file a complaint (both state and federal). 10 to 20
complaints are enough to get the feds moving on a
mail-fraud/wire-fraud investigation. The laws protecting consumers
from magazine advertisement mail-order rip-offs are sufficiently
strong to cause server problems to a company in arrears. For one
thing just the act of filing so many complaints can make it
difficult for a small company to raise money from sources that
are smart enough to check for such things. And if things get serious
enough the post office can cut off their mail (quite a screw eh?),
not to mention the criminal penalties that hang over them.
On the other hand, given the effort of making an example of
a company like this, and given how much work it is to do a reasonable
Scheme implementation on top of any halfway decent lisp,
maybe it would be better for us to pitch in and come up with
and advertise for distribution-at-cost some true Scheme implementation?
It would probably be less work (although maybe less fun) than screwing
some losing company to the wall.
-gjc
∂22-Jul-85 1043 @MIT-MC.ARPA:gls@THINK-AQUINAS.ARPA truth in advertisement
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Jul 85 10:43:49 PDT
Received: from THINK.ARPA by MIT-MC.ARPA 22 Jul 85 13:42:58 EDT
Received: by THINK.ARPA with CHAOS; Mon, 22 Jul 85 13:39:45 edt
Date: Mon, 22 Jul 85 13:41 EDT
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: truth in advertisement
To: GJC@MIT-MC.ARPA, SCHEME@MIT-MC.ARPA, linus!ramsdell@MITRE-BEDFORD.ARPA
Cc: gls@THINK-AQUINAS.ARPA
In-Reply-To: <[MIT-MC.ARPA].582540.850720.GJC>
Message-Id: <850722134121.2.GLS@UBALDO.ARPA>
Well, if you believe that the company is truly sinister and trying to
rip people off with shoddy merchandise, then all the legal apparatus
that GJC describes may be brought to bear. But it may be that the lack
of tail-recursion is due to incompetence, ignorance, oversight, or maybe
even an intentional tradeoff made to gain something else. There is a
lot to be said for first writing or calling the company and reporting it
as a bug and politely asking how soon it will be fixed. What you do
next depends on their reaction.
--Guy
∂22-Jul-85 1522 GJC@MIT-MC.ARPA truth in advertisement
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Jul 85 15:22:45 PDT
Date: Mon, 22 Jul 85 18:23:54 EDT
From: George J. Carrette <GJC@MIT-MC.ARPA>
Subject: truth in advertisement
To: gls@THINK-AQUINAS.ARPA
cc: SCHEME@MIT-MC.ARPA, linus!ramsdell@MITRE-BEDFORD.ARPA
In-reply-to: Msg of Mon 22 Jul 85 13:41 EDT from Guy Steele <gls at THINK-AQUINAS.ARPA>
Message-ID: <[MIT-MC.ARPA].584702.850722.GJC>
I just saw the price of the thing, $10K for the DEC/VAXLISP version.
Now considering the DEC/VAXLISP cost is $12k, charging $10K
for a three or four page lisp program that does syntactic
translation of Scheme code into Common-Lisp code is a bit
absurd. The question is what has been written in "T" that
has that kind of economic value? Evidently a few things!
Or it could be the case of Unix costing $300 from Berkeley
or a Unix emulator under VMS costing you a minimum of $8k.
∂24-Jul-85 1622 @MIT-MC.ARPA:linus!ramsdell@mitre-bedford
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 24 Jul 85 16:22:09 PDT
Received: from mitre-bedford by MIT-MC.ARPA 24 Jul 85 19:20:04 EDT
Date: 24 Jul 1985 17:35:50-EDT
From: linus!ramsdell@Mitre-Bedford
Received: by linus.UUCP (4.12/4.7)
id AA16213; Wed, 24 Jul 85 08:00:35 edt
Date: Wed, 24 Jul 85 08:00:35 edt
From: linus!ramsdell (John D. Ramsdell)
Message-Id: <8507241200.AA16213@linus.UUCP>
To: bccvax!scheme@mit-mc.arpa
Received: by linus.UUCP (4.12/4.7)
id AA07000; Tue, 23 Jul 85 07:57:28 edt
Date: Tue, 23 Jul 85 07:57:28 edt
From: ramsdell (John D. Ramsdell)
Message-Id: <8507231157.AA07000@linus.UUCP>
To: bccvax!scheme@mit-mc.arpa
Subject: CSI Lisp
Cc: bccvax!meehan@yale
In my opinion, CSI Lisp was implemented by knowledgeable
people who know very well about tail recursion optimization.
They are not the kind of people that would leave it out
because its too hard to figure out. In fact, their Apollo
implementation reliably does the optimization. They left
it out from some implementations because they wanted to port
their programs to machines by implementing their lisp on top
of existing systems. Since Common Lisp and Lisp-VM are not
required to do the opimization, they realized that they would
incure much pain and suffering if they spend the effort to
get it right in these lisps. Reasonable people doing
reasonable things. My only complaint is that reasonable
people reading their ad in CACM would conclude that all their
implementations are tail recursive.
Cognitive Systems should be applauded for porting a dialect
of lisp that is much simpler than Common Lisp, yet just as
useful. I think it is important to recognise the good
with the bad. Comments and questions about CSI Lisp
should be directed to Jim Meehan (MEEHAN@YALE).
John
∂24-Jul-85 1929 @MIT-MC.ARPA:OXLEY%ti-csl.csnet@csnet-relay.arpa Scheme Not Tail Recursive!!!????
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 24 Jul 85 19:26:06 PDT
Received: from csnet-relay by MIT-MC.ARPA 24 Jul 85 22:26:05 EDT
Received: from ti-csl by csnet-relay.csnet id ac16288; 24 Jul 85 7:55 EDT
Date: 23 Jul 1985 1602-CDT
From: Don Oxley <OXLEY%CSL60%ti-csl.csnet@csnet-relay.arpa>
Subject: Scheme Not Tail Recursive!!!????
To: Willc%tekchips%tektronix.csnet@csnet-relay.arpa
cc: Scheme@mit-mc.ARPA
Received: from csl60 by ti-csl; Wed, 24 Jul 85 00:53 CST
In reading the revised, revised report, I can find no statement - either
direct or inferred, that Scheme is required to be properly tail
recursive.
Did I overlook something?
I suggest a requirement to that effect be inserted (as an errata if
necessary) on page 8.
A much more picky point. On page 7, is the statement that ALL objects
have unlimited extent. Since fluid variables have dynamic extent, it
seems to me that a picky interpretation could preclude fluid variables
in the language (the counter argument of course is that is a sufficient
base to implement fluids). Would a bit of clarification be helpful?
--Don
PS. Sorry for nitpicking AFTER the report is out, but sometimes you
have to be writing your own manual to be able to read another carefully.
-------
∂24-Jul-85 1944 @MIT-MC.ARPA:willc%tekchips%tektronix.csnet@csnet-relay.arpa Re: Scheme Not Tail Recursive!!!????
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 24 Jul 85 19:43:51 PDT
Received: from csnet-relay by MIT-MC.ARPA 24 Jul 85 22:44:31 EDT
Received: from tektronix by csnet-relay.csnet id ac20001; 24 Jul 85 21:42 EDT
From: Will Clinger <willc%tekchips%tektronix.csnet@csnet-relay.arpa>
To: oxley%ti-csl.csnet@csnet-relay.arpa
Cc: scheme@MIT-MC.ARPA
Received: from tekchips by tektronix with smtp ; 24 Jul 85 17:47:51 PDT
Date: Wednesday, 24 Jul 85 17:33:05 PDT
Subject: Re: Scheme Not Tail Recursive!!!????
In-reply-to: Your message of 23 Jul 1985 1602-CDT.
Finite Memories Considered Harmful (same song, second verse)
Tail recursion is an implementation issue rather than a matter of
semantics. Gedanken experiment: the Incredibly Big Machine
Corporation decides that it can increase its profits by compiling
tail recursion improperly while bundling its machines with a contract
that calls for customers to add 10↑13 bytes of RAM each month as part
of preventive maintenance.
Likewise garbage collection is an implementation issue, not a matter
of semantics. There's nothing in the Revised Revised Report to
mandate a garbage collector.
On the other hand: Anything that causes programs to run out of
memory is a bug.
It may be that the Incredibly Big Machine Corporation is shipping a
bug-free product. That cannot be said for any implementation that
uses a finite memory.
It is philosophically inconsistent to insist upon proper treatment of
tail recursion and upon garbage collection while allowing finite
memories. Of course, people know to ask about the finite memory bug
when they purchase a computer. Indeed, the bug is often advertised.
Not so many people know to ask about tail recursion and garbage
collectors, so maybe we should be inconsistent.
William Clinger
∂25-Jul-85 0342 @MIT-MC.ARPA:GJS@MIT-OZ Re: Scheme Not Tail Recursive!!!????
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 25 Jul 85 03:39:15 PDT
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 25 JUL 85 06:39:15 EDT
Date: Thu 25 Jul 85 06:39:18-EDT
From: Gerald Jay Sussman <GJS%MIT-OZ@MIT-MC.ARPA>
Subject: Re: Scheme Not Tail Recursive!!!????
To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
cc: oxley%ti-csl.csnet@CSNET-RELAY.ARPA, scheme@MIT-MC.ARPA
In-Reply-To: Message from "Will Clinger <willc%tekchips%tektronix.csnet@csnet-relay.arpa>" of Wed 24 Jul 85 22:47:15-EDT
Unless anyone objects, I will insert a one-liner stating that we expect
both tail-recursion and dynamic storage allocation and deallocation are
assumed in any legit implementation (consistent with modern hardware implementations)
-------
∂25-Jul-85 1115 JAR@MIT-MC.ARPA Are fluids objects?
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 25 Jul 85 11:15:22 PDT
Date: Thu, 25 Jul 85 14:16:00 EDT
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: Are fluids objects?
To: OXLEY%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA
cc: SCHEME@MIT-MC.ARPA,
Willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
Message-ID: <[MIT-MC.ARPA].587507.850725.JAR>
Date: 23 Jul 1985 1602-CDT
From: Don Oxley <OXLEY%CSL60%ti-csl.csnet at csnet-relay.arpa>
A much more picky point. On page 7, is the statement that ALL objects
have unlimited extent. Since fluid variables have dynamic extent, it
seems to me that a picky interpretation could preclude fluid variables
in the language (the counter argument of course is that is a sufficient
base to implement fluids). Would a bit of clarification be helpful?
I'm no semantics wiz, but I think that "object" is used consistently in
the Scheme and Lisp literature to mean what corresponds to "expressed
value" in denotational semanticses. Perhaps this point should be made
somewhere. But I believe that if this point is understood, nothing need
be said about fluids, since they are not necessarily objects (expressed
values). Anything at all can have dynamic extent if it pleases, as
long as it is not an object.
On the other hand, I don't think the report should preclude language
extensions, and some of these extensions might include various kinds of
second-class citizens, including perhaps objects with only dynamic
extent. (I don't think I'd do such a thing, but someone else might.)
If other people agree with me on this, maybe some clarification of the
statement on page 7 is in order.
Jonathan
∂25-Jul-85 1125 @MIT-MC.ARPA:JINX@MIT-OZ Scheme Not Tail Recursive!!!????
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 25 Jul 85 11:24:56 PDT
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 25 JUL 85 14:09:08 EDT
Date: 25 Jul 1985 11:49 EDT (Thu)
Message-ID: <JINX.12129837829.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Don Oxley <OXLEY%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA>
Cc: Scheme@MIT-MC.ARPA, Willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
Subject: Scheme Not Tail Recursive!!!????
In-reply-to: Msg of 23 Jul 1985 17:02-EDT from Don Oxley <OXLEY%CSL60%ti-csl.csnet at csnet-relay.arpa>
I think we should be fairly harsh about this issue. I don't consider
an implementation which is not properly tail recursive an acceptable
implementation. Note also that by properly tail recursive I don't
mean something which just "optimizes" reduction self-calls, but rather
one that keeps a minimum amount of state on any reduction.
I don't understand your objections about the extent of fluid
variables. I don't think a variable binding is an object, and
certainly in the context of the report there is no way of obtaining it
or manipulating it as an object (so it would not be first class at
least). Not being an object, its extent can be limited. However, the
objects being "dynamically bound" must certainly have unlimited
extent. This difference is similar to the difference between a macro
(whatever that may be), and a macro expander, which is a legitimate
object (probably a procedure). Both variable bindings and macros are
conceptual entities with no counterpart in the language, the objects
bound to and the macro expanders are "real" objects which are subject
to the same contraints as all other objects.
Note also that even if something has formally unlimited extent, if an
implementation can prove that it is no longer accessible it can
recalim its storage. This is what gc is based on, but nobody claims
that any implementation must wait until an actual system-wide gc to
reclaim pieces of storage.
∂25-Jul-85 1310 @MIT-MC.ARPA:JINX@MIT-OZ previous message
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 25 Jul 85 13:09:52 PDT
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 25 JUL 85 16:08:23 EDT
Date: 25 Jul 1985 15:39 EDT (Thu)
Message-ID: <JINX.12129879691.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
Subject: previous message
To: scheme@MIT-MC.ARPA
I apologize for my previous message, the message does not read as I
expected. It was certainly not my intent to to alienate anybody.
∂26-Jul-85 1444 @MIT-MC.ARPA:BARTLEY%ti-csl.csnet@csnet-relay.arpa Re: Scheme Not Tail Recursive!!!????
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 26 Jul 85 14:42:59 PDT
Received: from csnet-relay by MIT-MC.ARPA 26 Jul 85 17:43:23 EDT
Received: from ti-csl by csnet-relay.csnet id ah08928; 26 Jul 85 17:36 EDT
Date: 25 Jul 1985 1055-CDT
From: David Bartley <Bartley%CSL60%ti-csl.csnet@csnet-relay.arpa>
Subject: Re: Scheme Not Tail Recursive!!!????
To: GJS%MIT-OZ@mit-mc.ARPA, willc%tekchips%tektronix.csnet@csnet-relay.arpa
cc: oxley%ti-csl.csnet@csnet-relay.arpa, scheme@mit-mc.ARPA,
Bartley%CSL60%ti-csl.csnet@csnet-relay.arpa
In-Reply-To: Your message of 25-Jul-85 0638-CDT
Received: from csl60 by ti-csl; Thu, 25 Jul 85 13:06 CST
I agree with Don and Gerry. The standard has to take some notice of the
finiteness of machines (why else have INEXACT?). Also, the 1978 revised
report specifically states that "Scheme is implemented in such a way that
tail-recursions execute without net growth of the interpreter stack."
Leaving such a statement out of the revised revised report would seem to
imply that the language has changed in that respect.
-------
∂26-Jul-85 2251 @MIT-MC.ARPA:BARTLEY%ti-csl.csnet@csnet-relay.arpa Ambiguous number syntax
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 26 Jul 85 22:50:57 PDT
Received: from csnet-relay by MIT-MC.ARPA 27 Jul 85 01:51:17 EDT
Received: from ti-csl by csnet-relay.csnet id ae10910; 27 Jul 85 1:46 EDT
Date: 26 Jul 1985 1006-CDT
From: David Bartley <Bartley%CSL60%ti-csl.csnet@csnet-relay.arpa>
Subject: Ambiguous number syntax
To: Scheme@mit-mc.ARPA
cc: Bartley%CSL60%ti-csl.csnet@csnet-relay.arpa,
MMeyer%CSL60%ti-csl.csnet@csnet-relay.arpa
Received: from csl60 by ti-csl; Fri, 26 Jul 85 18:48 CST
(1) The RRReport states on page 48 that <radix16> is denoted by #h or #H,
while stating on page 50 that the prefix for hex values is #X. Since
Common Lisp uses #X for "hexadecimal rational" values, we prefer to believe
that the mention of #H on page 48 is a typographical error. Would anyone
like to argue otherwise?
(2) Is it possible to write a number in base 16 scientific notation? How
is the letter 'e' or 'E' to be interpreted -- as a hex digit or the start
of the exponentiation suffix?
David Bartley,
Mark Meyer
-------
∂27-Jul-85 1715 @MIT-MC.ARPA:GJS@MIT-OZ Re: Ambiguous number syntax
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 27 Jul 85 17:15:17 PDT
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 27 JUL 85 20:15:38 EDT
Date: Sat 27 Jul 85 20:14:38-EDT
From: Gerald Jay Sussman <GJS%MIT-OZ@MIT-MC.ARPA>
Subject: Re: Ambiguous number syntax
To: Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA
cc: Scheme@MIT-MC.ARPA, MMeyer%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA
In-Reply-To: Message from "David Bartley <Bartley%CSL60%ti-csl.csnet@csnet-relay.arpa>" of Fri 26 Jul 85 11:06:00-EDT
I am doing the last pass now...
(1) The RRReport states on page 48 that <radix16> is denoted by #h or #H,
while stating on page 50 that the prefix for hex values is #X. Since
Common Lisp uses #X for "hexadecimal rational" values, we prefer to believe
that the mention of #H on page 48 is a typographical error. Would anyone
like to argue otherwise?
That was indeed a typo. I will fix it.
(2) Is it possible to write a number in base 16 scientific notation? How
is the letter 'e' or 'E' to be interpreted -- as a hex digit or the start
of the exponentiation suffix?
I don't really have a good idea about that. Perhaps we should defer
any decisions until someone wants to do it! (sounds unlikely). I actually
hate hex and wish it would go away.
-------
∂29-Jul-85 1020 @MIT-MC.ARPA:gls@THINK-AQUINAS.ARPA Re: Ambiguous number syntax
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 29 Jul 85 10:20:23 PDT
Received: from THINK.ARPA by MIT-MC.ARPA 29 Jul 85 13:11:25 EDT
Received: by THINK.ARPA with CHAOS; Mon, 29 Jul 85 13:07:02 edt
Date: Mon, 29 Jul 85 13:06 EDT
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: Re: Ambiguous number syntax
To: GJS%MIT-OZ@MIT-MC.ARPA, Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA
Cc: Scheme@MIT-MC.ARPA, MMeyer%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA,
gls@THINK-AQUINAS.ARPA
In-Reply-To: The message of 27 Jul 85 20:14-EDT from Gerald Jay Sussman <GJS%MIT-OZ at MIT-MC>
Message-Id: <850729130650.4.GLS@POLYCARP.ARPA>
Date: Sat 27 Jul 85 20:14:38-EDT
From: Gerald Jay Sussman <GJS%MIT-OZ@MIT-MC.ARPA>
I am doing the last pass now...
(1) The RRReport states on page 48 that <radix16> is denoted by #h or #H,
while stating on page 50 that the prefix for hex values is #X. Since
Common Lisp uses #X for "hexadecimal rational" values, we prefer to believe
that the mention of #H on page 48 is a typographical error. Would anyone
like to argue otherwise?
That was indeed a typo. I will fix it.
(2) Is it possible to write a number in base 16 scientific notation? How
is the letter 'e' or 'E' to be interpreted -- as a hex digit or the start
of the exponentiation suffix?
I don't really have a good idea about that. Perhaps we should defer
any decisions until someone wants to do it! (sounds unlikely). I actually
hate hex and wish it would go away.
-------
I cannot resist passing on one proposal for radix syntax that was
considered for Common Lisp (and rejected, so take it with a grain of
salt!).
First, observe thsat traditional mathematical syntax for a radix is a
trailing subscript:
1000 = 512
8 10
Second, observe that many non-LISP languages uses parentheses or brackets
for subscripting. Well, we can't use parentheses, so try brackets:
(EQUAL? 1000[8] 512[10])
For historical compatibility, we also allow 512. to mean the same as
512[10] . Therefore "." means the same as "[10]". So extend this
notion to the floating-point notation:
3.14159265 means the same as 3[10]14159265
and now we have an unambiguous place to put the radix:
3[10]1415926535 approximately equals 3[8]11037552
If you really can't stand that, we could settle for 3.11037552[8],
where the "[...]" overrides the decimalness of the ".".
This still doesn't solve the problem of whether "E" is a hex digit or an
exponent marker. Well, the "E" serves two purposes" as a delimiter
between significand and exponent, and as a precision indicator (other
choices are "D" and perhaps "S", "F", "L", or whatever). One might wish
to measure precision in bits. So gobble down "<...>" for this purpose.
Then "E" is just an abbreviation for "<24>" or whatever:
Pi is approximately [8]311037552<24>+1
If "E" might be taken as a digit, then one must write "<24>" or "<E>".
Pretty horrible, huh?
--Guy
∂30-Jul-85 2036 GJC@MIT-MC.ARPA Ambiguous number syntax
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 30 Jul 85 20:35:57 PDT
Date: Tue, 30 Jul 85 22:59:41 EDT
From: George J. Carrette <GJC@MIT-MC.ARPA>
Subject: Ambiguous number syntax
To: gls@THINK-AQUINAS.ARPA
cc: SCHEME@MIT-MC.ARPA, Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA,
MMeyer%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA, GJS@MIT-OZ
In-reply-to: Msg of Mon 29 Jul 85 13:06 EDT from Guy Steele <gls at THINK-AQUINAS.ARPA>
Message-ID: <[MIT-MC.ARPA].594615.850730.GJC>
Fortunately there is always #.(J-RANDOM-NUMBER "...random syntax")
∂31-Jul-85 1159 @MIT-MC.ARPA:CPH@MIT-OZ identifiers and symbols
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 31 Jul 85 11:58:59 PDT
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 31 JUL 85 14:57:20 EDT
Date: Wed, 31 Jul 1985 14:52 EDT
Message-ID: <CPH.12131444141.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: Snyder%hplabs.csnet@CSNET-RELAY.ARPA
Cc: Scheme@MIT-MC.ARPA
Subject: identifiers and symbols
In-reply-to: Msg of 30 Jul 1985 15:54-EDT from Snyder%hplabs.csnet at csnet-relay.arpa
Date: Tuesday, 30 July 1985 15:54-EDT
From: Snyder%hplabs.csnet at csnet-relay.arpa
To: cph at mit-mc.ARPA
Re: identifiers and symbols
Source-Info: From (or Sender) name not authenticated.
In reading the draft Scheme report, it appears that the possibility is left
open for identifiers and symbols to be distinct. For example, the first
paragraph in Section II.5 says that symbols are often used to represent
identifiers, implying that other alternatives are possible. Is this correct?
If so, are identifiers defined as objects (how do they behave)? Does read of
"X" return an identifier or a symbol?
Alan Snyder
Technically, these two types might be distinct. Practically speaking,
there seems little point in doing so. But there is no reason that the
report should contain this unnecessary bias.
On the other hand, since it is (perhaps) universally true that they
are not distinct, I guess that Will did not think the extra effort of
completely separating them was worth it. Trying to decide which gets
used where (e.g. in READ) might take some time. And if you just
assume that they are the same, then (I think) the rest of the report
is pretty consistent.
But I'm just guessing. I'll forward this to Scheme@MC, which will get
you a much wider range of opinions -- that is the best place to send
mail concerning the report, since everyone who helped make it will be
available to reply.
∂31-Jul-85 1445 JAR@MIT-MC.ARPA identifiers and symbols
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 31 Jul 85 14:45:30 PDT
Date: Wed, 31 Jul 85 17:46:03 EDT
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: identifiers and symbols
To: Snyder%hplabs.csnet@CSNET-RELAY.ARPA
cc: SCHEME@MIT-MC.ARPA, CPH@MIT-OZ
Message-ID: <[MIT-MC.ARPA].595673.850731.JAR>
Date: Tuesday, 30 July 1985 15:54-EDT
From: Snyder%hplabs.csnet at csnet-relay.arpa
In reading the draft Scheme report, it appears that the
possibility is left open for identifiers and symbols to be
distinct. For example, the first paragraph in Section II.5 says
that symbols are often used to represent identifiers, implying
that other alternatives are possible. Is this correct? If so,
are identifiers defined as objects (how do they behave)? Does
read of "X" return an identifier or a symbol?
I think you're confusing domains which Lisp blurs, but that the report
takes care to distinguish. The beginning of section II.1, "special
forms," says that identifiers, whose syntax is given previously, have
two uses (i.e. occur in the grammar in the rhs of two productions): as
<expression>'s, where they name variables; and inside of <datum>'s,
where they notate symbols, a particular kind of value. Identifiers,
being syntactic, can no more be user-level objects (i.e. values) than
can combinations or special forms.
Your typical Lisp manual (including, I hate to say, the T manual) starts
out the other way around by saying that data (lists, symbols, numbers)
can be notated using character strings of a certain form, and then says
that data can be interpreted as being program: a symbol can be a
variable name, a list can be a combination, etc. The Scheme report asks
you to imagine that the fact that programs and data are notated pretty
similarly is coincidental. It never says that a program is "read" from
a file using a READ function, and then parsed and interpreted through a
separate mechanism. Conceivably some poor soul could translate the
grammar from the Scheme report into YACC, and write a Scheme system in
C, in which maybe identifiers are represented as arrays of small
integers, and symbols and lists never come into existence at all, except
when a (QUOTE ...) form is evaluated, STRING->SYMBOL is called, etc.
The representation of identifiers, like that of numbers, is completely
invisible to the user.
READ of "X" presumably invokes that part of the Scheme parser which
deals with the <datum> nonterminal, and returns the appropriate value,
as if you had evaluated (QUOTE X) instead of (READ ...); so the value
would be a symbol.
I think that the statement in section II.4, "Even Lisp and Scheme
programs are lists," while true in spirit, is not accurate. But it's
difficult to come up with a concise way to connect the two concepts.
You'd have to say something to the effect that any sequence of terminals
derivable from the nonterminal <expression> could also be derived from the
nonterminal <datum> (can this be inferred from the report? Can 'foo and
`(a ,b) be derived from <datum>?).
Sorry to be so pedantic... I hope this clarifies things.
Jonathan
∂01-Aug-85 0915 @MIT-MC.ARPA:BARTLEY%ti-csl.csnet@csnet-relay.arpa Re: identifiers and symbols
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 1 Aug 85 09:14:50 PDT
Received: from csnet-relay by MIT-MC.ARPA 1 Aug 85 12:05:09 EDT
Received: from ti-csl by csnet-relay.csnet id ad01020; 1 Aug 85 11:54 EDT
Date: 31 Jul 1985 1808-CDT
From: David Bartley <Bartley%CSL60%ti-csl.csnet@csnet-relay.arpa>
Subject: Re: identifiers and symbols
To: CPH%MIT-OZ@mit-mc.ARPA, Snyder%hplabs.csnet@csnet-relay.arpa
cc: Scheme@mit-mc.ARPA, Bartley%CSL60%ti-csl.csnet@csnet-relay.arpa
In-Reply-To: Your message of 31-Jul-85 1658-CDT
Received: from csl60 by ti-csl; Wed, 31 Jul 85 19:05 CST
In reading the draft Scheme report, it appears that the possibility is left
open for identifiers and symbols to be distinct. For example, the first
paragraph in Section II.5 says that symbols are often used to represent
identifiers, implying that other alternatives are possible. Is this correct?
If so, are identifiers defined as objects (how do they behave)? Does read of
"X" return an identifier or a symbol?
Alan Snyder
I think of an "identifier" as a non-terminal in the grammar, while a
"symbol" is a datatype, so identifiers are not objects, and READ of X
returns a symbol.
The reason identifiers and symbols are distinct is that we don't want to
impose the implementation requirement that a Scheme program must be
internally represented as an s-expression. In particular, an identifier in
a program may be lexically processed by a compiler without passing through
READ at all, and therefore need not be represented as a symbol. Having
identifiers and symbols obey the same syntax rules is just a way to
facilitate the representation of identifiers by symbols, but it doesn't
require it.
I periodically pick this nit because many non-Schemers confuse "symbols"
with "variables." Further distinguishing "symbols" from "identifiers" is
meaningful to me, and seems to be implied by Will's wording, but may be
more controversial. Does anyone else see things this way, or am I outside
the pale (again)?
David Bartley
-------
∂02-Aug-85 1338 @MIT-MC.ARPA:mw%brandeis.csnet@csnet-relay.arpa Re: identifiers and symbols
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 2 Aug 85 13:38:38 PDT
Received: from csnet-relay by MIT-MC.ARPA 2 Aug 85 16:39:03 EDT
Received: from brandeis by csnet-relay.csnet id aa09446; 2 Aug 85 16:31 EDT
Received: by brandeis.ARPA (4.12/4.7)
id AA00810; Fri, 2 Aug 85 11:46:14 edt
Date: 2 Aug 1985 11:39-EST
From: mw%brandeis.csnet@csnet-relay.arpa
In-Real-Life: Mitchell Wand,faculty
Subject: Re: identifiers and symbols
To: David Bartley <Bartley%CSL60%ti-csl.csnet@csnet-relay.arpa>
Cc: scheme@mit-mc.ARPA
Message-Id: <491845196/mw@brandeis>
In-Reply-To: David Bartley's message of 31 Jul 1985 1808-CDT
←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←
From BARTLEY%ti-csl.csnet%CSNET-RELAY@MIT-MC.ARPA Thu Aug 1 16:24:38 1985
Date: 31 Jul 1985 1808-CDT
From: David Bartley <Bartley%CSL60%ti-csl.csnet@CSNET-RELAY>
Subject: Re: identifiers and symbols
To: CPH%MIT-OZ@MIT-MC, Snyder%hplabs.csnet@CSNET-RELAY
Cc: Scheme@MIT-MC, Bartley%CSL60%ti-csl.csnet@CSNET-RELAY
Status: O
In reading the draft Scheme report, it appears that the possibility is left
open for identifiers and symbols to be distinct. For example, the first
paragraph in Section II.5 says that symbols are often used to represent
identifiers, implying that other alternatives are possible. Is this correct?
If so, are identifiers defined as objects (how do they behave)? Does read of
"X" return an identifier or a symbol?
Alan Snyder
I think of an "identifier" as a non-terminal in the grammar, while a
"symbol" is a datatype, so identifiers are not objects, and READ of X
returns a symbol.
The reason identifiers and symbols are distinct is that we don't want to
impose the implementation requirement that a Scheme program must be
internally represented as an s-expression. In particular, an identifier in
a program may be lexically processed by a compiler without passing through
READ at all, and therefore need not be represented as a symbol. Having
identifiers and symbols obey the same syntax rules is just a way to
facilitate the representation of identifiers by symbols, but it doesn't
require it.
I periodically pick this nit because many non-Schemers confuse "symbols"
with "variables." Further distinguishing "symbols" from "identifiers" is
meaningful to me, and seems to be implied by Will's wording, but may be
more controversial. Does anyone else see things this way, or am I outside
the pale (again)?
David Bartley
-------
←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←
Yes, I think you've got it right. Identifiers are part of the external
syntax of Scheme programs; symbols are a kind of data manipulated by
those programs. Symbols have an external representation as character
strings, which typically, though not necessarily, coincides with the
external syntax of identifiers.
One of the most important differences between Lisp and Scheme is, as
you point out, the rigid separation between programs and data, and
between syntax and semantics. Most Lisp dialects constrain programs to
be maintained as S-expressions; Scheme very carefully does not. For
more on this, see the paper by Muchnick and Pleban, A Semantic
Comparison of Lisp and Scheme, in the 1980 Lisp Conference.
-- Mitch
∂05-Aug-85 1836 @MIT-MC.ARPA:unc!dyb%unc.csnet@csnet-relay.arpa Re: identifiers and symbols
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 5 Aug 85 18:35:56 PDT
Received: from csnet-relay by MIT-MC.ARPA 5 Aug 85 21:36:53 EDT
Received: from unc by csnet-relay.csnet id ah10818; 5 Aug 85 21:29 EDT
Received: from unc (dopey) by thorin (4.12/4.7)
id AA15806; Mon, 5 Aug 85 00:03:04 edt
Received: by unc (4.12/4.7)
id AA25673; Mon, 5 Aug 85 00:03:23 edt
Date: Mon, 5 Aug 85 00:03:23 edt
From: Kent Dybvig <unc!dyb%unc.csnet@csnet-relay.arpa>
Message-Id: <8508050403.AA25673@unc>
To: Bartley%CSL60%ti-csl.csnet@csnet-relay.arpa,
mw%brandeis.csnet@csnet-relay.arpa
Subject: Re: identifiers and symbols
Cc: scheme@mit-mc.ARPA
In reading the draft Scheme report, it appears that the possibility is left
open for identifiers and symbols to be distinct. For example, the first
paragraph in Section II.5 says that symbols are often used to represent
identifiers, implying that other alternatives are possible. Is this correct?
If so, are identifiers defined as objects (how do they behave)? Does read of
"X" return an identifier or a symbol?
Alan Snyder
I think of an "identifier" as a non-terminal in the grammar, while a
"symbol" is a datatype, so identifiers are not objects, and READ of X
returns a symbol.
The reason identifiers and symbols are distinct is that we don't want to
impose the implementation requirement that a Scheme program must be
internally represented as an s-expression. In particular, an identifier in
a program may be lexically processed by a compiler without passing through
READ at all, and therefore need not be represented as a symbol. Having
identifiers and symbols obey the same syntax rules is just a way to
facilitate the representation of identifiers by symbols, but it doesn't
require it.
I periodically pick this nit because many non-Schemers confuse "symbols"
with "variables." Further distinguishing "symbols" from "identifiers" is
meaningful to me, and seems to be implied by Will's wording, but may be
more controversial. Does anyone else see things this way, or am I outside
the pale (again)?
David Bartley
-------
←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←
Yes, I think you've got it right. Identifiers are part of the external
syntax of Scheme programs; symbols are a kind of data manipulated by
those programs. Symbols have an external representation as character
strings, which typically, though not necessarily, coincides with the
external syntax of identifiers.
One of the most important differences between Lisp and Scheme is, as
you point out, the rigid separation between programs and data, and
between syntax and semantics. Most Lisp dialects constrain programs to
be maintained as S-expressions; Scheme very carefully does not. For
more on this, see the paper by Muchnick and Pleban, A Semantic
Comparison of Lisp and Scheme, in the 1980 Lisp Conference.
-- Mitch
←←←←←←←←←←←←←←←←←←
I think that we should point out that certain objects may be
translated into Scheme expressions, with emphasis on translation
(that is, say that it may require writing the object to a file and
handing the compiler the resulting file). If we loose the idea of
"program as data" people will wonder what we are still using all
these parentheses for.
To allow the potential for translation requires that we agree upon a
common representation for programs as data. The natural one is the
one that prints the way we expect, with symbols denoting identifiers
and special form keywords. The wording might go, "If a Scheme object
is to be translated into a Scheme program, identifiers are represented
by symbols, special forms are represented by lists, ..." This does
require the syntax for identifiers to be a subsyntax (?) of the syntax
for symbols.
In spite of the conclusions of Muchnick and Pleban, I believe that we
should support an object-level representation for Scheme programs.
One of the beauties of Scheme is the ability to write macro processors
and compilers for Scheme in Scheme (easily), and the lack of this
ability is the one thing I dislike most about ML.
Kent
∂05-Aug-85 1851 @MIT-MC.ARPA:CPH@MIT-OZ identifiers and symbols
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 5 Aug 85 18:51:22 PDT
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 5 AUG 85 21:51:34 EDT
Date: Mon, 5 Aug 1985 21:49 EDT
Message-ID: <CPH.12132830745.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: Kent Dybvig <unc!dyb%unc.csnet@CSNET-RELAY.ARPA>
Cc: Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA,
mw%brandeis.csnet@CSNET-RELAY.ARPA, scheme@MIT-MC.ARPA
Subject: identifiers and symbols
In-reply-to: Msg of 5 Aug 1985 00:03-EDT from Kent Dybvig <unc!dyb%unc.csnet at csnet-relay.arpa>
Date: Monday, 5 August 1985 00:03-EDT
From: Kent Dybvig <unc!dyb%unc.csnet at csnet-relay.arpa>
I think that we should point out that certain objects may be
translated into Scheme expressions, with emphasis on translation
(that is, say that it may require writing the object to a file and
handing the compiler the resulting file).
I personally am opposed to any mention of files or compilers in such a
manner. These are completely orthogonal to what I consider the
essence of the programming language (and programming environment), and
serve only the cloud the real issues, not clear them up. Ideally I
would like an environment without files, and without any explicit
compilation, in which all of that non-essential stuff happens
transparently to me. I'm interested in writing and debugging
procedures and data structures, not files of characters.
If we lose the idea of "program as data" people will wonder what
we are still using all these parentheses for.
Independent of the "program as data" feature, those parentheses are
still an essential aspect of the SIMPLICITY of Scheme (and Lisp)
syntax. This is, I think, even more important than the fact that a
Scheme program is representable as a data structure. One can, for
example, represent a Pascal or C program as a data structure in one of
those languages (albeit clumsily), but that does not make the external
syntax any simpler.
To allow the potential for translation requires that we agree upon a
common representation for programs as data.
I think that this is completely irrelevant as we have not included the
EVAL procedure in the Scheme standard. Nothing else in the standard
relates to such a representation in any way.
∂09-Aug-85 1539 JAR@MIT-MC.ARPA Altering quoted structure
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 9 Aug 85 15:39:30 PDT
Date: Fri, 9 Aug 85 18:40:58 EDT
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: Altering quoted structure
To: SCHEME@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].607100.850809.JAR>
I would like to point out a small problem in an example in section II.4,
"Pairs and lists." The following interaction:
(define x '(a b c)) --> x
(define y x) --> y
(set-cdr! x 4) --> unspecified
x --> (a . 4)
(eq? x y) --> #!true
y --> (a . 4)
will not necessarily work in implementations (e.g., Yale's) where quoted
structure may be stored in read-only memory.
I don't think the report says anything about quoted structure being
immutable, but I think that it is very important that implementations be
allowed to make them be read-only. I recommend that the description of
QUOTE (which is perhaps too terse even for my taste) be amended
appropriately.
The example can easily be fixed: just write
(define x (list 'a 'b 'c))
instead of
(define x '(a b c)) .
While the report can only specify that modifying quoted structure "is an
error," I would consider it any implementation which doesn't detect such
modifications to be deficient. It isn't done because it's difficult.
Jonathan
∂09-Aug-85 1546 JAR@MIT-MC.ARPA (EQV? #\? #\?) ?
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 9 Aug 85 15:46:05 PDT
Date: Fri, 9 Aug 85 18:47:31 EDT
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: (EQV? #\? #\?) ?
To: SCHEME@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].607113.850809.JAR>
Could we agree that EQV? should do a CHAR=? comparison on characters?
Jonathan?
∂09-Aug-85 1549 JAR@MIT-MC.ARPA Altering quoted structure, addendum
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 9 Aug 85 15:49:49 PDT
Date: Fri, 9 Aug 85 18:51:15 EDT
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: Altering quoted structure, addendum
To: SCHEME@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].607118.850809.JAR>
The example
(define vec '#(0 (2 2 2 2) "Anna")) --> vec
(vector-set! vec 1 '("Sue" "Sue")) --> unspecified
vec --> #(0
("Sue" "Sue")
"Anna")
is also at fault, and can be fixed the same way as the other one.
Jonathan.
∂09-Aug-85 1618 @MIT-MC.ARPA:JINX@MIT-OZ (EQV? #\? #\?) ?
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 9 Aug 85 16:18:48 PDT
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 9 AUG 85 19:20:04 EDT
Date: 9 Aug 1985 19:18 EDT (Fri)
Message-ID: <JINX.12133851721.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Jonathan A Rees <JAR@MIT-MC.ARPA>
Cc: SCHEME@MIT-MC.ARPA
Subject: (EQV? #\? #\?) ?
In-reply-to: Msg of 9 Aug 1985 18:47-EDT from Jonathan A Rees <JAR at MIT-MC.ARPA>
yes!!
∂09-Aug-85 1623 @MIT-MC.ARPA:JINX@MIT-OZ Altering quoted structure
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 9 Aug 85 16:23:11 PDT
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 9 AUG 85 19:24:22 EDT
Date: 9 Aug 1985 19:22 EDT (Fri)
Message-ID: <JINX.12133852458.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Jonathan A Rees <JAR@MIT-MC.ARPA>
Cc: SCHEME@MIT-MC.ARPA
Subject: Altering quoted structure
In-reply-to: Msg of 9 Aug 1985 18:40-EDT from Jonathan A Rees <JAR at MIT-MC.ARPA>
I agree with you even though MIT Scheme does not detect alterations
to quoted structure. I think the report should say it is an error to
modify them.
PS : What do you do about Gcing quoted structure if it is in read-only
memory? Is it not garbage-collectable? Is the garbage collector
special?
∂12-Aug-85 0745 JAR@MIT-MC.ARPA delay, force, cons-stream
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 12 Aug 85 07:45:45 PDT
Date: Mon, 12 Aug 85 10:47:18 EDT
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: delay, force, cons-stream
To: SCHEME@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].609180.850812.JAR>
Could someone remind me why DELAY, FORCE, and CONS-STREAM aren't in the
RRReport, even non-essentially? This absence seems inconsistent with
the presence of SEQUENCE, which exists only because it appears in S&ICP.
DELAY, FORCE, and CONS-STREAM also are used in S&ICP.
Jonathan
∂16-Sep-85 1306 JAR@MIT-MC.ARPA report; scheme in CL; trace
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 16 Sep 85 13:06:21 PDT
Date: Mon, 16 Sep 85 16:06:36 EDT
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: report; scheme in CL; trace
To: SCHEME@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].646835.850916.JAR>
[Topic #1:] MIT AI memo 848, the Revised Revised Report on Scheme, is
back from the printer. The text is exactly the same as what most of you
received in the mail about a month ago, but is is now available in
quantity, and is has a nice binding with a blue cover. They can be
ordered from:
Elizabeth Heepe
Publications, Room NE43-818
MIT Artifical Intelligence Laboratory
545 Technology Square
Cambridge MA 02139
Enclose a check for $6.00 per copy (U.S. funds) payable to the MIT
Artificial Intelligence Laboratory. If you are strapped for cash or you
need it quickly, I can send you one directly myself, bypassing the
publications office.
[Topic #2:] I have written, as a quick hack, and with the generous
support of DEC, an implementation of the essential subset (and a little
more) of RRRSS, in Common Lisp. (RRRSS is my abbreviation for Revised
Revised Report on Scheme Scheme.) It works by translating RRRSS into
Common Lisp; tail recursion is accomplished by compiling calls in a
peculiar way (incompatible with the host Common Lisp's procedure caall,
which will not necessarily be tail recursive at the right time). If you
are interested in testing it out for me, and sending remarks & bug
reports, I'd be grateful. The plan is to eventually make this part of
the Common Lisp "Yellow Pages." I'll mail the source code to anyone
requesting it.
[Topic #3:] I'm curious to know how implementors have dealt with the
problem of causing trace (i.e. debugging) packages to interact properly
with (DEFINE (FOO ...) ...). I.e. if one says (TRACE FOO) [or (TRACE
'FOO) or whatever your local syntax is], one would like all recursive
calls from FOO to itself to be traced. Especially tricky to make this
work with native-code compilers. I think this was one reason why in T
we made (DEFINE (FOO ...) ...) be the same as (DEFINE FOO (LAMBDA (.
...) ...)), instead of using the MIT and RRRSS semantics, because then TRACE
can be implemented at the source code level, as (SET! FOO
(MAKE-TRACED-PROCEDURE FOO)), without any need to know the underlying
representation. What have other people done?
Jonathan
∂17-Sep-85 1312 @MIT-MC.ARPA:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: report; scheme in CL; trace
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 17 Sep 85 13:12:13 PDT
Received: from CSNET-RELAY.ARPA by MIT-MC.ARPA 17 Sep 85 15:39:06 EDT
Received: from indiana by csnet-relay.csnet id a014789; 17 Sep 85 15:33 EDT
Date: Tue, 17 Sep 85 10:19:37 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: MIT-MC!JAR%unc.csnet@CSNET-RELAY.ARPA, SCHEME@mit-mc.ARPA
Subject: Re: report; scheme in CL; trace
Chez Scheme supports two interfaces for tracing. One is
available to the user after his program is entered (the
normal "trace" interface) and the other must be imbedded in
the program ("trace-lambda" or "trace-recur").
"trace" works only as you say, for the outermost invocation
of a function created with "defrec", and not at all for let-
or letrec-bound lambda expressions. Using "trace-lambda" in
place of "lambda" or "trace-recur" in place of "recur" causes
the same tracing that "trace" provides.
In order to provide the user with a handle on the traced
function, the "trace-lambda" syntax requires an identifier to
precede the formal parameters.
The only disadvantage of "trace-lambda" is that the program
must be reentered to be traced. This can have a significant
impact on an interactive session unless multiple windows are
provided.
Kent Dybvig
dyb.Indiana@CSnet-Relay
∂22-Oct-85 2253 @MIT-MC.ARPA:meltsner%athena@mit-eddie.MIT.EDU Scheme for Thermo.
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Oct 85 22:53:04 PDT
Received: from mit-eddie by MIT-MC.ARPA 21 Oct 85 14:22:10 EDT
Received: from MIT-CHARON (d003a12) by mit-eddie (4.12/4.7)
id AA25774; Mon, 21 Oct 85 14:19:13 edt
Received: by MIT-CHARON (4.12/4.7)
id AA02813; Mon, 21 Oct 85 14:23:10 edt
Message-Id: <8510211823.AA02813@MIT-CHARON>
To: scheme@mit-mc, ai-ed@sumex-aim
Cc: meltsner@mit-charon
Subject: Scheme for Thermo.
Date: 21 Oct 85 14:22:51 EDT (Mon)
From: meltsner%athena@mit-eddie.MIT.EDU
This is both a request and an announcement:
I have been working on a "microworld" for thermodynamics. The world
would support common thermodynamic objects like gases and solids, and would
allow objects to be interconnected, and equilibriums found with a variety
of constraints on mass, energy, volume, etc. transfer. ("would" because
not all features have been implemented)
It has proved to be useful in an introductory (graduate) level thermo course,
and I am currently planning to rewrite it to remedy a number of deficiencies.
Questions:
1) Would you prefer an english-language (command-driven) interface or a
windowed one? Does "make an gas with 10 moles of neon temperature 298" make
more sense than a dialog box after one has selected a menu item "Make Gas"?
2) Are windowed graphics useful? What sort of graphics?(x-time, x-y, contour,
dials, gauges, empty/full bar indicators)
3) Would you sacrifice speed for numeric accuracy? (1% accuracy vs. .01% might
triple the iteration time)
4) How important are on-line help, explanations of internal processes,
examples?
5) What would you like to have it run on? (4.2 Unix, Macintosh, IBM, ??)
6) What would it have to run on to be useful for use in a class at your
institution?
The program is currently written in T, and will be moved to Cscheme (MIT
Vax 4.2 Unix Scheme in C).
The program is available for trade or (in a few months) for a nominal
fee from our group at MIT. Planned expansions include the ability to
change thermodynamic state variables, a thermo methods database
(rule-driven thermo), and a clock for kinetic problems.
Please send all answers and questions to:
meltsner@athena.MIT.EDU
or Ken Meltsner
MIT Room 13-5142
Cambridge, MA 02139 617-253-3139
Ken
∂22-Oct-85 2253 JAR@MIT-MC.ARPA scheme implementations
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Oct 85 22:53:33 PDT
Date: Mon, 21 Oct 85 16:08:06 EDT
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: scheme implementations
To: SCHEME@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].687283.851021.JAR>
To make sure that everyone out there has current information, I want to
ask people who have or are actively working on Scheme implementations to
send out a SHORT message, giving the following information:
- Name of implementation
- Implemented by whom
- Supported by whom, and to what extent
- Hardware and operating system(s)
- Availability: when, approximate pricing, copyright status
- Description of dialect (esp. compare with RRRSS [*] and with the
dialect used in S&ICP)
- Intended use: education, number crunching, systems programming, etc.
- Implementation style (S-code, native-code-compiler-based, or whatever)
- Remarks, interesting features, misfeatures, and applications, etc.
- Whom to contact for more information
In particular, I'd like to hear blurbs from the groups at Indiana, MIT,
Semantic Microsystems, TI, Yale, Vincennes, and Cadence. No hype please.
[* Sorry, I use the following abbreviations:
S&ICP = the book "Structure and Interpretation of Computer Programs"
by Abelson & Sussman
RRRSS = the Scheme dialect described in the Revised Revised Report
ERRRSS = the "essential" subset of RRRSS]
If you have written books or articles about or using Scheme or are in
the process of doing so, I think people would be interested in hearing
about that too.
∂22-Oct-85 2334 JAR@MIT-MC.ARPA welcome
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Oct 85 23:34:05 PDT
Date: Sun, 20 Oct 85 21:46:23 EDT
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: welcome
To: SCHEME@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].686441.851020.JAR>
Welcome to the "Scheme" mailing list. The list is intended to be a
forum for discussing anything related to the Scheme programming
language(s), with particular emphasis on the use of Scheme in education.
There are over 100 people on the list now, with about 70 institutions
represented. Most have signed up as the result of a recent message
on AILIST.
Send all communication concerning the administration of the list
(additions, removals) to Scheme-Request@MIT-MC.
Some of you may be unwittingly on this list (e.g., indirectly through
some other list). Send mail to Scheme-Request@MIT-MC if you don't want
to be on and I'll try to fix things somehow.
Messages will accrete in the file "LSPMAI; SCHEME MAIL" on MIT-MC.
Several people have asked about MIT AI memo 848, the "Revised Revised
Report on Scheme," Will Clinger, editor. It can be ordered from:
Elizabeth Heepe
Publications, Room NE43-818
MIT Artifical Intelligence Laboratory
545 Technology Square
Cambridge MA 02139
Enclose a check for $6.00 per copy (U.S. funds) payable to the MIT
Artificial Intelligence Laboratory.
Coming soon: information on available and unavailable Scheme
implementations.
Jonathan Rees
JAR@MIT-MC
∂22-Oct-85 2351 JAR@MIT-MC.ARPA Implementation blurb: Scheme in Common Lisp
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Oct 85 23:51:21 PDT
Date: Mon, 21 Oct 85 20:27:49 EDT
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: Implementation blurb: Scheme in Common Lisp
To: SCHEME@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].687556.851021.JAR>
- Name of implementation:
CLSCH (Scheme embedded in Common Lisp)
- Implemented by whom:
Jonathan Rees
- Supported by whom, and to what extent:
Unsupported, although I'll probably continue to improve it. No promises.
- Hardware and operating system(s):
Will run in any implementation of Common Lisp.
- Availability:
In alpha-test now (looking for guinea pigs). Free. Distributed as
source via electronic mail or FTP. (I won't make tapes.) May
eventually become part of Common Lisp "Yellow Pages."
- Description of dialect:
Subset. All of the essential features of RRRSS exist, except for a
correct CALL-WITH-CURRENT-CONTINUATION (some of you will say that it's
not Scheme at all, and I don't disagree); also some of the rest of
RRRSS, and most of the S&ICP dialect.
- Intended use:
Running existing ERRRSS programs in any Common Lisp. Not an ideal
development system, since debugging tools are weak.
- Implementation style:
Low-tech. A simple compiler translates Scheme into Common Lisp, making
sure that variable binding and tail recursion are done right. The
output of the compiler can be interpreted by a CL interpreter or
compiled by a CL compiler.
- Remarks:
I did this mostly for my own personal use. Maybe other people will find
it useful too.
- Contact:
Jonathan Rees (JAR@MIT-MC), MIT Artificial Intelligence Laboratory,
545 Technology Square, Cambridge MA 02139, (617) 253-8581.
∂23-Oct-85 2107 JAR@MIT-MC.ARPA Implementation blurb: Vincennes Scheme
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 23 Oct 85 21:07:25 PDT
Date: Thu, 24 Oct 85 00:08:44 EDT
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: Implementation blurb: Vincennes Scheme
To: SCHEME@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].690739.851024.JAR>
Since I doubt anyone from Univ. de Paris 8 is on this list, I'll send
out what information I have on Vincennes Scheme.
- Jonathan
---
Vincennes Scheme is a version of Scheme written entirely in portable
C, for Unix V7 and Berkeley 4.1 and 4.2. It runs on 32-bit machines
(e.g. 68K or Vax) as well as on 16-bit machines (e.g. Z8000 in which
it can fit in 128K). This Scheme is compatible with the MIT version,
and includes an interpreter with the basic environment: debugger,
history, break, stepper, where. A compiler that generates C code is
available. For more information, contact
Patrick Greussay
Universite Paris-8-Vincennes
2 rue de la Liberte
Saint-Denis CEDEX 02 93526
France
∂23-Oct-85 2322 @MIT-MC.ARPA:narain@rand-unix.ARPA Elementary question about backquote in T.
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 23 Oct 85 23:22:02 PDT
Received: from rand-unix.ARPA by MIT-MC.ARPA 24 Oct 85 01:02:18 EDT
Return-Path: <narain@rand-unix.ARPA>
Received: by rand-unix.ARPA; Wed, 23 Oct 85 21:59:52 pdt
From: Sanjai Narain <narain@rand-unix.ARPA>
Message-Id: <8510240459.AA18070@rand-unix.ARPA>
Date: 23 Oct 85 21:59:49 PDT (Wed)
To: scheme@mit-mc
Subject: Elementary question about backquote in T.
I hope it is okay to send a T question to this list, since I am not aware
of a separate list for T.
If we define:
(define-macro (bar x) `(list ,(car x)))
then (macro-expand '(bar '(1 2)) *scratch-env*) ==> (list quote). That is, an
attempt to evaluate (bar '(1 2)) will give an error to the effect that
quote is unbound.
This appears to me rather confusing. A macro is ideally a rewrite rule.
So I expect (bar '(1 2)) to be rewritten to the form (list u) where
u = (car '(1 2)) i.e. (list u) must be rewritten to (list 1).
This expectation is supported by the following observations:
> (set x '(1 2))
;; x is bound to '(1 2)
> `(list ,(car x))
==> (list 1)
What am I missing? By the way, Franzlisp backquote behaves similarly.
Thanks for any comments.
-- Sanjai
∂24-Oct-85 0856 @MIT-MC.ARPA:gls@THINK-AQUINAS.ARPA Elementary question about backquote in T.
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 24 Oct 85 08:56:36 PDT
Received: from GODOT.THINK.COM by MIT-MC.ARPA 24 Oct 85 11:57:26 EDT
Received: from jehosephat by GODOT.THINK.COM via CHAOS; Thu, 24 Oct 85 11:57:31 edt
Date: Thu, 24 Oct 85 11:59 EDT
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: Elementary question about backquote in T.
To: narain@RAND-UNIX.ARPA, scheme@MIT-MC.ARPA
Cc: gls@THINK-AQUINAS.ARPA
In-Reply-To: <8510240459.AA18070@rand-unix.ARPA>
Message-Id: <851024115916.2.GLS@THINK-JEHOSEPHAT.ARPA>
Date: 23 Oct 85 21:59:49 PDT (Wed)
From: Sanjai Narain <narain@rand-unix.ARPA>
...
If we define:
(define-macro (bar x) `(list ,(car x)))
then (macro-expand '(bar '(1 2)) *scratch-env*) ==> (list quote). That is, an
attempt to evaluate (bar '(1 2)) will give an error to the effect that
quote is unbound.
This appears to me rather confusing. A macro is ideally a rewrite rule.
So I expect (bar '(1 2)) to be rewritten to the form (list u) where
u = (car '(1 2)) i.e. (list u) must be rewritten to (list 1).
No, u = (car ''(1 2)).
This expectation is supported by the following observations:
> (set x '(1 2))
;; x is bound to '(1 2)
No, x is bound to (1 2). The car of this is then 1.
> `(list ,(car x))
==> (list 1)
What am I missing? By the way, Franzlisp backquote behaves similarly.
Thanks for any comments.
-- Sanjai
For absolute precision, in the following remarks I will use
double-quotes as metasyntactic quote marks, rather than as string
delimiters.
In the macro call "(bar '(1 2))" the macro parameter "x" is bound to an
unevaluated argument, so the value of "x" is "'(1 2)", which is the same
as "(quote (1 2))". When you write ",(car x)" within the backquote, it
means to take the car of the macro-expand-time value of "x". The value
of "x" is "(quote (1 2))", so the car of that is "quote".
The resdult of expanding "(bar (1 2))" (without a single quote) would be
"(list 1)", which wpould then evaluate to "(1)".
One could also define "bar" as
(define-macro (bar x) `(list (car ,x)))
with the comma in a different place, so as to make the "car" operation
take place at evaluation time (run time) rather than expansion time
(compile time). Then the macro call "(bar '(1 2))" would expand to
"(list (car '(1 2)))" which would in turn also evaluate to "(1)".
--Guy
∂24-Oct-85 1201 @MIT-MC.ARPA:RAM@YALE.ARPA Re: Elementary question about backquote in T.
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 24 Oct 85 11:17:01 PDT
Received: from yale by MIT-MC.ARPA 24 Oct 85 14:00:07 EDT
Received: by Yale-Bulldog.YALE.ARPA; 24 Oct 85 13:31:16 EDT (Thu)
Message-Id: <8510241731.AA00535@Yale-Bulldog.YALE.ARPA>
Received: from YALE-RING by YALE-RES via CHAOS; Thu, 24 Oct 85 13:06:11 EDT
Subject: Re: Elementary question about backquote in T.
Date: Thu, 24 Oct 85 13:06:14 EDT
From: Ashwin Ram <Ram@YALE.ARPA>
To: Sanjai Narain <narain@RAND-UNIX>
Cc: scheme@MIT-MC
In-Reply-To: Sanjai Narain <narain@rand-unix.ARPA>, 23 Oct 85 21:59:49 PDT (Wed)
I'm sure you'll get a lot of responses to your question, but anyway...
I hope it is okay to send a T question to this list, since I am not aware
of a separate list for T.
There are two: T-USERS and T-DISCUSSION. There was once a reason for having
separate lists but in practice everyone now reads both and there doesn't seem
to be any real difference in the type or level of questions.
If we define:
(define-macro (bar x) `(list ,(car x)))
then (macro-expand '(bar '(1 2)) *scratch-env*) ==> (list quote). That is, an
attempt to evaluate (bar '(1 2)) will give an error to the effect that
quote is unbound.
This appears to me rather confusing. A macro is ideally a rewrite rule.
So I expect (bar '(1 2)) to be rewritten to the form (list u) where
u = (car '(1 2)) i.e. (list u) must be rewritten to (list 1).
This expectation is supported by the following observations:
> (set x '(1 2))
;; x is bound to '(1 2)
> `(list ,(car x))
==> (list 1)
What am I missing? By the way, Franzlisp backquote behaves similarly.
Thanks for any comments.
-- Sanjai
---------
The single-quote character is a read macro that wraps a QUOTE around its
argument. In T terms, that means the following:
> (stream-read-table (standard-input))
#{Read-table 53 *STANDARD-READ-TABLE*}
> (read-table-entry (stream-read-table (standard-input)) #\')
#{Procedure 54 READ-QUOTATION}
and, from TSYS/READ.T:
(DEFINE (READ-QUOTATION STREAM CH RT)
(IGNORE CH)
(LIST *QUOTE* (READ-OBJECT-REFUSING-EOF STREAM RT)))
Thus '(1 2) gets read in as (QUOTE (1 2)), and (bar '(1 2)) expands to
(LIST u) where u is the CAR of (QUOTE (1 2)), i.e., the symbol QUOTE.
In other words, (bar '(1 2)) expands to (list QUOTE) as you noted.
Macros are rewrite rules, but on list structures (like "(QUOTE (1 2))"), not
on ASCII text (like "'(1 2)"). In your transcript, x gets bound, not to
"'(1 2)" as you say, but to a list structure represented as (1 2). The CAR
of this structure is the atom 1, and thus you get (list 1), i.e., the list
(1) as your result.
Hope this helps... Ashwin.
-------
∂24-Oct-85 1331 JAR@MIT-MC.ARPA T mailing lists.
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 24 Oct 85 13:30:47 PDT
Date: Thu, 24 Oct 85 16:31:38 EDT
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: T mailing lists.
To: narain@RAND-UNIX.ARPA
cc: SCHEME@MIT-MC.ARPA
In-reply-to: Msg of Thu 24 Oct 85 13:06:14 EDT from Ashwin Ram <Ram at YALE.ARPA>
Message-ID: <[MIT-MC.ARPA].691724.851024.JAR>
I'll put you, and anyone else who wants to be, on the T lists. I think
their existence is mentioned in the front of the T Manual. In general,
requests should be sent to T-Discussion-Request@MIT-MC. (T-Users was
intended as a one-way communications channel from implementors to users
for announcements, etc., and T-Discussion was intended to be a forum.)
∂24-Oct-85 1443 @MIT-MC.ARPA:narain@rand-unix.ARPA Q. on backquote
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 24 Oct 85 14:43:13 PDT
Received: from rand-unix.ARPA by MIT-MC.ARPA 24 Oct 85 15:32:29 EDT
Return-Path: <narain@rand-unix.ARPA>
Received: by rand-unix.ARPA; Thu, 24 Oct 85 12:18:48 pdt
From: Sanjai Narain <narain@rand-unix.ARPA>
Message-Id: <8510241918.AA29049@rand-unix.ARPA>
Date: 24 Oct 85 12:18:45 PDT (Thu)
To: scheme@mit-mc
Subject: Q. on backquote
Thanks to all of you for taking the time to respond to my question. I realize
much of what you say for I have been using the facility for quite a while.
My intention was to understand it precisely. Fundamentally, it is a question
of what is the need to quote and what is evaluation. Note that Prolog
doesn't need to quote, neither does the lambda calculus.
-- Sanjai
∂25-Oct-85 0945 @MIT-MC.ARPA:HUDAK@YALE.ARPA Re: Q. on backquote
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 25 Oct 85 09:45:11 PDT
Received: from yale by MIT-MC.ARPA 25 Oct 85 10:23:27 EDT
Received: by Yale-Bulldog.YALE.ARPA; 25 Oct 85 10:10:52 EDT (Fri)
Message-Id: <8510251410.AA08341@Yale-Bulldog.YALE.ARPA>
Received: from YALE-RING by YALE-RES via CHAOS; Fri, 25 Oct 85 10:10:41 EDT
Subject: Re: Q. on backquote
Date: Fri, 25 Oct 85 10:10:42 EDT
From: Paul Hudak <Hudak@YALE.ARPA>
To: Sanjai Narain <narain@RAND-UNIX>
Cc: scheme@MIT-MC
In-Reply-To: Sanjai Narain <narain@rand-unix.ARPA>, 24 Oct 85 12:18:45 PDT (Thu)
...
Fundamentally, it is a question of what is the need to quote and
what is evaluation. Note that Prolog doesn't need to quote, neither
does the lambda calculus.
Please -- T/Scheme doesn't need to quote either -- one can usually
use closures to do what you want. It's just that macros are useful
for defining *syntax*, and there's no reason that Prolog designers
won't reach the same conclusion. Although I personally shy away from
using macros, they are generally viewed as a *feature* of Lisps, but
not necessarily fundamental to the language or its semantics.
-Paul
∂26-Oct-85 1019 @MIT-MC.ARPA:WAXMAN@USC-ECL.ARPA PLASE REMOVE MY NAME FROM SCHEME MAILING LIST
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 26 Oct 85 10:05:43 PDT
Received: from USC-ECL.ARPA by MIT-MC.ARPA 26 Oct 85 13:06:47 EDT
Date: 26 Oct 1985 1002-PDT
From: WAXMAN@USC-ECL.ARPA
Subject: PLASE REMOVE MY NAME FROM SCHEME MAILING LIST
To: JAR@MIT-MC.ARPA
cc: SCHEME@MIT-MC.ARPA
JONATHON,
PLEASE REMOVE MY NAME FROM THE SCHEME ELECTRONIC MAIL LIST.
IT HAS MORE DETAIL THAN I NEED.
THANKS,
MILT WAXMAN
WAXMAN@USC-ECLA
-------
∂28-Oct-85 0740 JAR@MIT-MC.ARPA moderation
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Oct 85 07:40:25 PST
Date: Mon, 28 Oct 85 10:41:43 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: moderation
To: SCHEME@MIT-MC.ARPA
In-reply-to: Msg of 27 Oct 85 00:21:50 EDT (Sun) from yba at ATHENA.MIT.EDU
Message-ID: <[MIT-MC.ARPA].695148.851028.JAR>
I have received several messages of the following form:
Date: 27 Oct 85 00:21:50 EDT (Sun)
From: yba at ATHENA.MIT.EDU
Or could we at least get it moderated so as to ensure it
discusses scheme instead of backquotes in T? How about just
asking folks not to cc the entire list? Please?
If you have any doubt as to whether a message you want to send is
appropriate for the list, send it to SCHEME-REQUEST@MIT-MC, and I'll
either forward it or reply to it. For the moment, I'll act as
"moderator" when that's needed. I don't want to spend too much time
on this, so please, moderate yourselves. Remember that turnaround can
be very slow, since many people are only connected through CSNET or
uucp. That explains why there were redundant replies to the backquote
question.
In defense of the recent backquote flurry, I'll say that the question
had nothing to do with T; backquote is a common feature of RRRSS, Common
Lisp, and many other Lisps. However, I agree that the question had
little to do with Scheme either. My perception is that most people are
on the list not because they're interested in language issues per se,
but rather because they want to talk about how people actually use the
unique aspects of Scheme in teaching and discussing computation. (Tell
me if I'm wrong.)
∂28-Oct-85 0824 JAR@MIT-MC.ARPA implementations
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Oct 85 08:24:21 PST
Date: Mon, 28 Oct 85 11:25:33 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: implementations
To: SCHEME@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].695198.851028.JAR>
Since no one has responded to my request for implementation info, I'll
send out excerpts from the standard letter that MIT sends to people who
ask about Scheme implementations. I hope this is useful to some of you.
Some of this information may be out of date. Please correct whatever's
wrong. I didn't include the paragraph on Chez Scheme since it gave a
UNC address and phone number, and it was my understanding that Chez
Scheme now comes from Cadence Research Inc., not UNC. Also, I don't
know who the official contact, if any, is for T. Information on the MIT
scheme implementations was too detailed, and most of you probably have
it already, so a condensed version will arrive under separate cover.
- Jonathan
@b[MacScheme] is a commercially-available implementation of Scheme for
the 512K Apple Macintosh. It meets the requirements of the Revised
Revised Report. A compatibility file is supplied for use with the
Abelson and Sussman book. The system features a byte-code interpreter
and Macintosh-style user interface. MacScheme sells for $125; site
licenses are available. For more information, write to:
@begin(display)
Semantic Microsystems
1001 Bridgeway Suite 543
Sausalito CA 94965
(415) 332-8094
@end(display)
@b[PC Scheme] (unofficial name) is an implementation of Scheme that is
being developed at Texas Instruments. It runs on the Texas
Instruments Personal Computer and the IBM Personal Computer. Besides
the Scheme interpreter itself, the system includes graphics, windowing
capabilities, and a text editor implemented in Scheme. The
implementation adheres to the Scheme standard, and it is completely
compatible with the MIT course material. The Scheme interpreter
itself will run in 256K, but successful course use (easily invoking
the editor, loading the largest MIT material) requires a system with
at least 512K and preferably a hard disk. PC Scheme is still under
development and is not available commercially. However, Texas
Instruments is conducting an instructional beta test program under
which they will make implementations available to institutions wishing
to use Scheme in conjunction with courses and other instructional
projects. For information on the program contact
@begin(display)
Texas Instruments
PO Box 2909
Austin, Texas 78769
Attn: Scheme Product Center, M/S 2244
@end(display)
@b[Scheme84] is a version of Scheme that has been under development at
Indiana University for the past few years, and is used there to
support half a dozen different computer science courses. The system
runs on the Vax under either VMS or Berkeley Unix. The developers of
Scheme84 intend to supply a compatibility package that will allow the
MIT materials to be run without modification. The Scheme84 software
is in the public domain, and can be obtained by writing to@foot{The
current distribution policy for Scheme84 is that Indiana University
will supply it for free, if you send them a tape and return postage.
(Please specify whether the system is to be for VMS or for Unix.) On
the other hand, the University reserves the right to begin charging a
fee to recover the cost of distribution, should this become
necessary.}
@begin(display)
Scheme84 Distribution
Nancy Garrett
c/o Dan Friedman
Department of Computer Science
Indiana University
Bloomington, Indiana
(812)-335-9770
E-mail address nlg@@indiana
@end(display)
@b[T] is a version of Scheme that was developed at Yale University, and is
available for distribution. The system runs on Vaxes under VMS or
Unix (Berkeley 4.1 or 4.2) and on the Apollo Domain. For more
information, contact [???] at Yale (203-436-0802) or write to
@begin(display)
Yale University Dept. of Computer Science
PO Box 2158
Yale Station
New Haven, CT 06520
@end(display)
∂28-Oct-85 1024 JAR@MIT-MC.ARPA implementations
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Oct 85 10:24:22 PST
Date: Mon, 28 Oct 85 13:25:34 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: implementations
To: SCHEME@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].695199.851028.JAR>
Since no one has responded to my request for implementation info, I'll
send out excerpts from the standard letter that MIT sends to people who
ask about Scheme implementations. I hope this is useful to some of you.
Some of this information may be out of date. Please correct whatever's
wrong. I didn't include the paragraph on Chez Scheme since it gave a
UNC address and phone number, and it was my understanding that Chez
Scheme now comes from Cadence Research Inc., not UNC. Also, I don't
know who the official contact, if any, is for T. Information on the MIT
scheme implementations was too detailed, and most of you probably have
it already, so a condensed version will arrive under separate cover.
- Jonathan
@b[MacScheme] is a commercially-available implementation of Scheme for
the 512K Apple Macintosh. It meets the requirements of the Revised
Revised Report. A compatibility file is supplied for use with the
Abelson and Sussman book. The system features a byte-code interpreter
and Macintosh-style user interface. MacScheme sells for $125; site
licenses are available. For more information, write to:
@begin(display)
Semantic Microsystems
1001 Bridgeway Suite 543
Sausalito CA 94965
(415) 332-8094
@end(display)
@b[PC Scheme] (unofficial name) is an implementation of Scheme that is
being developed at Texas Instruments. It runs on the Texas
Instruments Personal Computer and the IBM Personal Computer. Besides
the Scheme interpreter itself, the system includes graphics, windowing
capabilities, and a text editor implemented in Scheme. The
implementation adheres to the Scheme standard, and it is completely
compatible with the MIT course material. The Scheme interpreter
itself will run in 256K, but successful course use (easily invoking
the editor, loading the largest MIT material) requires a system with
at least 512K and preferably a hard disk. PC Scheme is still under
development and is not available commercially. However, Texas
Instruments is conducting an instructional beta test program under
which they will make implementations available to institutions wishing
to use Scheme in conjunction with courses and other instructional
projects. For information on the program contact
@begin(display)
Texas Instruments
PO Box 2909
Austin, Texas 78769
Attn: Scheme Product Center, M/S 2244
@end(display)
@b[Scheme84] is a version of Scheme that has been under development at
Indiana University for the past few years, and is used there to
support half a dozen different computer science courses. The system
runs on the Vax under either VMS or Berkeley Unix. The developers of
Scheme84 intend to supply a compatibility package that will allow the
MIT materials to be run without modification. The Scheme84 software
is in the public domain, and can be obtained by writing to@foot{The
current distribution policy for Scheme84 is that Indiana University
will supply it for free, if you send them a tape and return postage.
(Please specify whether the system is to be for VMS or for Unix.) On
the other hand, the University reserves the right to begin charging a
fee to recover the cost of distribution, should this become
necessary.}
@begin(display)
Scheme84 Distribution
Nancy Garrett
c/o Dan Friedman
Department of Computer Science
Indiana University
Bloomington, Indiana
(812)-335-9770
E-mail address nlg@@indiana
@end(display)
@b[T] is a version of Scheme that was developed at Yale University, and is
available for distribution. The system runs on Vaxes under VMS or
Unix (Berkeley 4.1 or 4.2) and on the Apollo Domain. For more
information, contact [???] at Yale (203-436-0802) or write to
@begin(display)
Yale University Dept. of Computer Science
PO Box 2158
Yale Station
New Haven, CT 06520
@end(display)
∂28-Oct-85 1158 @MIT-MC.ARPA:narain@rand-unix.ARPA Re: moderation
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Oct 85 11:57:56 PST
Received: from rand-unix.ARPA by MIT-MC.ARPA 28 Oct 85 14:57:35 EST
Return-Path: <narain@rand-unix.ARPA>
Received: by rand-unix.ARPA; Mon, 28 Oct 85 10:24:33 pst
From: Sanjai Narain <narain@rand-unix.ARPA>
Message-Id: <8510281824.AA14691@rand-unix.ARPA>
Date: 28 Oct 85 10:24:25 PST (Mon)
To: scheme@mit-mc
Subject: Re: moderation
In-Reply-To: Your message of Mon, 28 Oct 85 10:41:43 EST.
<[MIT-MC.ARPA].695148.851028.JAR>
The question I asked is not as trivial as it sounds to people who
seem to have objected to it. It has to do with the necessity of quoting
expressions, something which is absent from other systems such as Prolog.
Hudak made the mysterious comment that Scheme/T doesn't need
to quote either. Well, if you want to set x to the symbol a try typing
(set x a). In Prolog you can do X=a quite legitimately. The problem
is simply that in Lisps there is no way of distinguishing variables from
constant symbols of the same name. So, you must use quote. The matter
is further complicated in the use of backquotes and by the dubious
distinction between evaluation and macroexpansion. What is the purpose of
this distinction? In the lambda calculus evaluation is simply repeated
macroexpansion to the normal form.
What distinguishes Scheme/T from other Lisps but language issues such
as lexical scoping and higher order functions? Yes, what indeed? If people
don't seem to be interested in discussing such issues here, as Jonathan
implies, I understood the purpose of this list quite incorrectly. Sorry.
FYI hardly anyone objects like yba@athena.mit in other language-oriented
lists like Prolog, or Franz-friends.
-- Sanjai
∂28-Oct-85 1359 @MIT-MC.ARPA:bap@g.cs.cmu.edu Re: need for quoting in Lisp
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Oct 85 13:58:05 PST
Received: from G.CS.CMU.EDU by MIT-MC.ARPA 28 Oct 85 16:51:34 EST
Date: 28 Oct 1985 16:07-EST
From: Barak.Pearlmutter@G.CS.CMU.EDU
To: scheme@mit-mc
Subject: Re: need for quoting in Lisp
Message-Id: <499381673/bap@G.CS.CMU.EDU>
At first glance it seems odd that Lisp requires quoting while Prolog
and lambda-calculus do not. The reason is that Lisp attempts to be
it's own meta-language, allowing chunks of code to be treated as data.
This power carries with it the danger that code and data might be
confused, and QUOTE is the way in which the confussion is averted. To
illustrate very concretely, imagine a Schemelike language which is NOT
it's own metalanguage, in which there are no macros. For any
construct, we can tell unambiguously whether we have code or data
in our hands, and hence quoting will be unnecessary.
Let's call our emasculated Scheme Scheme0. In Scheme0, the symbols
manipulated by code will not be used to represent variables. Rather,
we will have two different kinds of symbols, which both have the
identity property but are distinguished. The read/print convention I
use will be that v-symbols will be lower case and d-symbols will be
upper case. V-symbols will never be allowed into data structures
manipulated by code; rather they can only be part of programs
themselves.
Similarly, we will have two different kinds of cons cells: the cons
cells that make up the lists used to represent function calls and
special forms, and another kind of cons cell used to construct lists
manipulated by Scheme0 programs. The read/print convention for these
will be that program cons cells use (...) and data cons cells use
[...]. We now have a situation much like that with numbers and strings
in regular lisps: data cons cells can never be used to mean program, so
need not be quoted, and similarly with data symbols. Semantics by
example:
Regular Scheme Scheme0
(car (append x y)) (car (append x y))
(car (quote (append x y))) (car [APPEND X Y])
(append (f x) (g (quote y)) (append (f x) (g Y) [H Z])
(quote (h z)))
(f (lambda (x) (f x (quote (f x))))) (f (lambda (x) (f x [F X])))
There are many routes to add metarepresentational power to Scheme0.
One is to identify v-symbols with d-symbols, and the same with lists,
thus requiring QUOTE to distinguish constants from code, but allowing
macros to be written. Another would be to force macros to be written
in another language, say Scheme0-1, which can manipulate both v-data
and d-data, and is written using v-prime-datatypes. Unfortunately,
this requires more and more datatypes as we move up levels in the
tower. Thus, a DOLIST macro written to apply to Scheme0 code would be
written in Scheme0-1, but then DOLIST couldn't be used in Scheme0-1
unless you rewrote it in Scheme0-2, etc. There is a way out of this
dilemma, as with 3LISP, but Lisp has chosen to take the first road and
bite the QUOTE bullet. It remains to be seen if Prolog will be able to
integrate more natural source to source transformations without going
the same route.
--Barak.
∂28-Oct-85 1441 GJC@MIT-MC.ARPA
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Oct 85 14:40:22 PST
Date: Mon, 28 Oct 85 17:41:39 EST
From: "George J. Carrette" <GJC@MIT-MC.ARPA>
To: JAR@MIT-MC.ARPA
cc: SCHEME@MIT-MC.ARPA
In-reply-to: Msg of Mon 28 Oct 85 15:27:44 EST from Jonathan A Rees <JAR at MIT-MC.ARPA>
Message-ID: <[MIT-MC.ARPA].695676.851028.GJC>
OK, Jonathon, here's my info message resent:
- Name of implementation: SIOD (Scheme In One Defun)
- Implemented by whom: GJC (George Carrette)
- Supported by whom, and to what extent: GJC, for use in LMI lisp classes.
- Hardware and operating system(s): LMI-LAMBDA, ZETA(FOO?)LISP.
- Availability: Given out at my "guest lectures" to LMI lisp classes.
- Description of dialect: Sufficient to run S&ICP problems I find
most interesting. Especially streams, the meta-linguistic abtraction section,
and the interpreter/hardware sections.
- Intended use: education. Both to introduce S&ICP and to show interpreter
implementation, also "WHY MACROS OR BAD, or WHY CANT YOU READ MY CODE?"
- Implementation style: The function SEVAL (scheme EVAL) is one DEFUN.
The "text" being interpreted is syntax-checked first, but is otherwise
just the obvious s-expression. The environment representation is an ALIST.
Because of the underlying simplicity it was possible to code
special cases such as look-ahead for simple variable lookup,
and primitives such as +,/,CAR,CDR, applied to simple variable lookups
without fear. There is very little overhead in the interpreter besides
variable lookup (a single instruction, %ASSQ) and environment consing,
(cheaper by the dozen and with the volatility based GC). The resulting
interpreter is somewhat gross because of its use of specialized
macrology, but is extremely fast, especially when compiled into
MICROCODE by the Microcompiler.
- Remarks: One reason for this was to see just how far a few hours work
on a simple idea implemented somewhat grossly could go. Whenever I was
too burned out to do design-level work or debugging work (presumably on
jobs that I was paid to do) I might feel like trying to code
another SIOD special case. It is also a study for "how much effort should
go into avoiding CONS, vs other things?" It could be interesting to
compare its efficiency with JAR's compiler-style CLSCH.
- Whom to contact for more information: GJC@MC.
∂28-Oct-85 1457 GJC@MIT-MC.ARPA moderation
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Oct 85 14:57:48 PST
Date: Mon, 28 Oct 85 17:59:04 EST
From: "George J. Carrette" <GJC@MIT-MC.ARPA>
Subject: moderation
To: narain@RAND-UNIX.ARPA
cc: SCHEME@MIT-MC.ARPA
In-reply-to: Msg of 28 Oct 85 10:24:25 PST (Mon) from Sanjai Narain <narain at rand-unix.ARPA>
Message-ID: <[MIT-MC.ARPA].695690.851028.GJC>
I think the problem was one of "oh no, not that again," for some of
the more experienced scheme/lisp hackers here. Even the most intense
personal discussions with participants such as Sussman, Hanson, etc.
never quite resolved some of these issues. There have been good
suggestions to solving the scoping problems of macros.
Anyway, people dont seem willing to rehash the elementary arguments
again.
∂28-Oct-85 1542 @MIT-MC.ARPA:JINX@MIT-OZ moderation
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Oct 85 15:42:40 PST
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 28 OCT 85 17:41:02 EST
Date: 28 Oct 1985 17:40 EST (Mon)
Message-ID: <JINX.12154816414.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Sanjai Narain <narain@RAND-UNIX.ARPA>
Cc: scheme@MIT-MC.ARPA
Subject: moderation
There are 2 possible uses of macros:
- To provide SYNTACTIC EXTENSIONS to the language for convenience and
clarity. This is the only legitimate use (as far as I'm concerned) of
a macro facility. Examples of this are COND (in terms of IF) and LET
(in terms of LAMBDA). Note that macros are needed for this case not
because of order of evaluation (the main difference, besides
assignment, between lambda calculus and Scheme), but rather because
the forms do not make sense as procedure applications. For example,
consider
(let ((y (+ 2 3))) (* y y))
in a position where y is not bound. If LET were a procedure, it would
receive 2 arguments ((y (+ 2 3))) and (* y y). But then y would be a
free variable in the above expression, irrelevant of the order of
evaluation, which is certainly not the desired effect. To obtain the
desired effect, something like a macro would be needed even in a
system which more closely modelled the lambda calculus. Thus there is
something to macros which normal order evaluation in the lambda
calculus does not provide.
When used this way they are mere re-write rules (even character level)
and evaluation plays no part in them. The re-write can be seen as
happening before the program is evaluated, since these expressions
would have no reasonable meaning otherwise. Back-quote and comma can
be seen as ways of specifying string substitution.
- To obtain the effects of normal order evaluation, locatives, or
fexprs in a simple applicative order system like Scheme. Consider,
for example, the standard Lisp SETF macro (not the T version which
falls into the previous category). This is however a MISUSE, as far
as I am concerned, and the desired effect should be obtained
otherwise. I believe it is in this case that all of the problems
about order of evaluation, etc. arise, which is not too surprising,
since a tool is being used for something other than its real purpose.
Just because a tool can be abused, it does not mean that it is wrong
or that it is inherently broken if it does not work when it is used
for a purpose other than its intended one.
∂28-Oct-85 1627 @MIT-MC.ARPA:HAL@MIT-OZ quote
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Oct 85 16:26:58 PST
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 28 OCT 85 17:58:03 EST
Date: Mon, 28 Oct 1985 17:58 EST
Message-ID: <HAL.12154819603.BABYL@MIT-OZ>
From: HAL%MIT-OZ@MIT-MC.ARPA
To: scheme@MIT-MC.ARPA
Subject: quote
This is a comment on Sanji Narain's response to Paul Hudak's response
to his remark about quote:
The question I asked is not as trivial as it sounds to people who
seem to have objected to it. It has to do with the necessity of quoting
expressions, something which is absent from other systems such as Prolog.
Hudak made the mysterious comment that Scheme/T doesn't need
to quote either. Well, if you want to set x to the symbol a try typing
(set x a). In Prolog you can do X=a quite legitimately. The problem
is simply that in Lisps there is no way of distinguishing variables from
constant symbols of the same name. So, you must use quote.
This is an important issue that is very much misunderstood.
Lisp chooses to blur the line between data structures that can be
manipulated, and expressions in the language itself. The reason for
doing this is that it leads to increased programming power. For
instance, one could make a pattern matcher in which various elements
of the patterns are simply (names of) Lisp procedures, thus leading to
ability to explicitly EVAL parts of the pattern.
If one wanted to give up this power, then one could choose essentially
any ad hoc way to distinguish expressions from data (e.g., one could
capitalize all identifiers, as does Prolog). Thus, in Prolog, one can
unambiguously write X=a (as Narain points out) but one cannot
unambiguously write X=Y, if the intent of this is to assign to X a
constant (written as Y), which is later to be assembled into a data
structure that is to be later interpreted as a Prolog program with an
identifier named Y.
Of course, there is nothing to stop one from writing a Prolog
evaluator in Prolog (and there are good reasons for doing so) but then
the quotation problem (distinguishing expressions in the Prolog that
is performing the evaluation from expression in the Prolog that is
being evaluated) arises just as it does in Lisp.
This is not to say that Lisp's (or Scheme's) treatment of quote is the
last word in handling this problem. See Brian Smith's thesis for an
alternative, and perhaps more consistent approach.
A couple of people have suggested to Sussman and me that we give up
using quote in our book, since it would make things easier for
students, and also make a simpler language from a theoretical point of
view. Our opinion is that quote (hence the ability to mix data and
expressions) provides a real source of power that is intimately
related to Lisp's ability to serve as an implementation vehicle for
embedded languages and programming environments. But we do make this
point in our book.
It would be nice to assemble a collection of good examples that use
quote in this way.
Note that the same issues underly the use of macros. Contrary to what
Narain asserts, macro expansion is not just lambda reduction. This is
true for SOME macros (like defining IF in terms of COND) but not true
for others (such as DO) where the elements of the from may not even be
syntactically valid Lisp (or Scheme) expressions.
∂28-Oct-85 1720 @MIT-MC.ARPA:SRIDHARAN@BBNG.ARPA Why quote?
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Oct 85 17:19:42 PST
Received: from BBNG.ARPA by MIT-MC.ARPA 28 Oct 85 19:58:55 EST
Date: Mon 28 Oct 85 17:58:28-EST
From: SRIDHARAN@BBNG.ARPA
Subject: Why quote?
To: scheme@MIT-MC.ARPA
1. Prolog does not have evaluation of function terms in its semantics.
All terms are what a Lisper might say always quoted. The counterpart
of the problem for Prolog is how to introduce evaluated terms.
Since it feasible to write term rewrite rules (albeit only directional ones)
some form of evaluation can be introduced, producing various degrees
of partial and lazy evaluation methods. But, there would be questions
similar to that of quoting, on under what circumstances what terms
will be evaluated.
2. It is true but somewhat misleading to say that Lambda-calculus has no
quoting.
(a) pure Lambda-calculus has no data structures; one can simulate data
structures by using closures in much the same way a cons-cell is defined
(in A&S book but also many other places) by a closure that returns its
first or second argument. If one wants not simulated data structures,
but a machine-dependent real data structures (or at least dependent upon
some architectural feature such as dereferencing of pointers), one has to
introduce quotation.
(b) simulated data structures will also introduce the confusion of quoting,
(car (lambda () a)) will be an irreducible expression; Scheme will generate
an error.
3. In Lisp implementations, since functions are called by value, one needs
to resort to tricks to get call by expression/reference. In most realistic
cases, the difference between these is one of efficiency. If an operation
can be done on the expression once and used many times, one perhaps wishes
to macro expand it or advise the compiler to do the processing once.
Since efficiency is a legitimate concern of programmers,
macros/quotes/compiling are in the game.
4. There is another mechanism besides macros one might use - partial
compilation or compile time calculation. If an expression e contains
a subexpression s that one wishes to be evaluated, and its value used
in its place, quite a bit of optimization can be handled this way.
Especially for people trying to do knowledge-based programming (not only
in rules but inother forms as well) a good deal of knowledge-dependency
might be evaluated in once and for all - only if a compiler allows us
to use evaluate-once expressions.
-------
∂28-Oct-85 1816 @MIT-MC.ARPA:JINX@MIT-OZ quote
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Oct 85 18:16:49 PST
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 28 OCT 85 21:14:26 EST
Date: 28 Oct 1985 21:13 EST (Mon)
Message-ID: <JINX.12154855097.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: HAL%MIT-OZ@MIT-MC.ARPA
Cc: scheme@MIT-MC.ARPA
Subject: quote
In-reply-to: Msg of 28 Oct 1985 17:58-EST from HAL
I don't understand why people object to quote and not to double-quote.
For me the identifier (variable name) FOO and 'FOO are two distinct
objects which have no relation except potential similarity in printed
form (like "FOO" when display is used). It is EVAL that is funny, in
the same way that linkers for all operating systems are funny in that
they transform what was previously considered passive data into active
data or programs.
∂29-Oct-85 0816 @MIT-MC.ARPA:gls@THINK-AQUINAS.ARPA Re: need for quoting in Lisp
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 29 Oct 85 08:16:01 PST
Received: from GODOT.THINK.COM by MIT-MC.ARPA 29 Oct 85 10:58:57 EST
Received: from polycarp by GODOT.THINK.COM via CHAOS; Tue, 29 Oct 85 10:59:07 est
Date: Tue, 29 Oct 85 11:00 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: Re: need for quoting in Lisp
To: Barak.Pearlmutter@G.CS.CMU.EDU, scheme@MIT-MC.ARPA
Cc: gls@THINK-AQUINAS.ARPA
In-Reply-To: <499381673/bap@G.CS.CMU.EDU>
Message-Id: <851029110027.1.GLS@THINK-POLYCARP.ARPA>
Date: 28 Oct 1985 16:07-EST
From: Barak.Pearlmutter@G.CS.CMU.EDU
... To
illustrate very concretely, imagine a Schemelike language which is NOT
it's own metalanguage, in which there are no macros. For any
construct, we can tell unambiguously whether we have code or data
in our hands, and hence quoting will be unnecessary.
...
To Mr. Pearlmutter's excellent exposition I would like to add the observation
that, 25 years ago, LISP was originally conceived in exactly these terms.
Allow me to add to the table of examples the representation as LISP
"M-expressions" ("meta-expressions"):
Regular Scheme Scheme0 M-expressions
(car (append x y)) (car (append x y)) car[append[x; y]]
(car (quote (append x y))) (car [APPEND X Y]) car[(APPEND X Y)]
(append (f x) (g (quote y)) (append (f x) (g Y) [H Z]) append[f[x]; g[Y]; (H Z)]
(quote (h z)))
--Guy
∂29-Oct-85 0842 JAR@MIT-MC.ARPA administrivia
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 29 Oct 85 08:42:46 PST
Date: Tue, 29 Oct 85 11:44:06 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: administrivia
To: SCHEME@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].696740.851029.JAR>
At least one person was confused about this, so I'll reiterate just to
make sure this is clear.
This list is not moderated. If you send mail to SCHEME@MIT-MC you're
sending a message out to about 150 people. Some of these people would
like to receive only pithy and extremely interesting messages. If you
have any doubt about the appropriateness of a message, send it to
SCHEME-REQUEST@MIT-MC and it will be moderated, forwarded, answered,
edited, critiqued, ignored, or subjected to some combination of the
the above. Thanks.
Actually I think it's been going pretty well, but I'd like to hear more
about the following: (a) implementations and (b) pedagogy.
∂29-Oct-85 1231 @MIT-MC.ARPA:cpd@LOCUS.UCLA.EDU Continuations
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 29 Oct 85 12:31:09 PST
Received: from LOCUS.UCLA.EDU by MIT-MC.ARPA 29 Oct 85 15:32:05 EST
Date: Tue, 29 Oct 85 12:11:06 PST
From: Charles Dolan <cpd@LOCUS.UCLA.EDU>
To: scheme@mit-mc.arpa
Subject: Continuations
Message-ID: <499464666-2399-cpd@ZEUS.LOCUS.UCLA.EDU>
At UCLA we use T which does not support continuations. I was wondering what
I am missing. What are people out there using continuations for? Do you
have simple examples which demonstrate how continuations make you solution
more elegant, efficient, ...?
-Charlie Dolan
∂30-Oct-85 0750 @MIT-MC.ARPA:HUDAK@YALE.ARPA Re: moderation
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 30 Oct 85 07:50:14 PST
Received: from yale by MIT-MC.ARPA 30 Oct 85 10:36:44 EST
Received: by Yale-Bulldog.YALE.ARPA; 30 Oct 85 09:59:36 EST (Wed)
Message-Id: <8510301459.AA07860@Yale-Bulldog.YALE.ARPA>
Received: from YALE-RING by YALE-RES via CHAOS; Wed, 30 Oct 85 09:51:03 EST
Subject: Re: moderation
Date: Wed, 30 Oct 85 09:51:05 EST
From: Paul Hudak <Hudak@YALE.ARPA>
To: Sanjai Narain <narain@RAND-UNIX>
Cc: scheme@MIT-MC
In-Reply-To: Sanjai Narain <narain@rand-unix.ARPA>, 28 Oct 85 10:24:25 PST (Mon)
Hudak made the mysterious comment that Scheme/T doesn't need to
quote either. ...
Sorry to sound mysterious. My intent was to point out, as others
have by now, that quoting wasn't *necessary*, just as it isn't in
the lambda calculus; it is simply convenient, as most meta-tools are.
So it seems to me that the only issue is that if one decides to have
a "meta-language," how should it be manifested -- perhaps that's what
you were refering to. Lisp chose quote, Prolog has a different
mechanism, Barak's "Scheme0" uses yet another. I suppose they all
have their advantages/disadvantages.
I should clarify one other aspect of my "mysterious" comment: QUOTE
is really just a way to create a data structure, and thus is not much
different from using, say, strings. However, it's combination with
EVAL is what makes me shy away from macros. It's usually the case
that if one is using QUOTE plus EVAL, there's a "cleaner" way to do
it with closures.
-Paul
P.S. I agree with you that these discussions are OK for this
mailing-list, but then again I'm not a Scheme expert who has
perhaps hashed through these issues a hundred times before.
∂30-Oct-85 0909 @MIT-MC.ARPA:cpd@LOCUS.UCLA.EDU Re: Continuations
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 30 Oct 85 09:09:32 PST
Received: from LOCUS.UCLA.EDU by MIT-MC.ARPA 30 Oct 85 11:43:50 EST
Date: Wed, 30 Oct 85 08:37:27 PST
From: Charles Dolan <cpd@LOCUS.UCLA.EDU>
To: Jim Meehan <Meehan@YALE.ARPA>
CC: scheme@mit-mc.arpa
Subject: Re: Continuations
In-reply-to: Message of Tue, 29 Oct 85 16:15:37 EST
from "Jim Meehan <Meehan@YALE.ARPA>"
<8510292121.AA02629@Yale-Bulldog.YALE.ARPA>
Message-ID: <499538247-20492-cpd@HERA.LOCUS.UCLA.EDU>
Heresy! Internally, T uses continuations all the time (surely
you've seen these while crawling through the stack with DEBUG).
Users can also write them either by passing LAMBDAs or by using
CATCH (which is even implemented as CALL-WITH-CONTINUATION). The
current T compiler doesn't take as much advantage of them as the
prototype T 3.0 compiler does. In terms of running Lisp code,
continuations are important for eliminating tail-recursion, etc. Take
a peek at Abelson & Sussman, "Sturcture and Interpretation of
Computer Programs." But for general programming, passing
continuations is very useful, particularly when you pass more
than one; each indicates "what to do next" (i.e., how to continue
the computation) in some particular case, which can lead to code
that's much more elegant than code that returns flags to the
caller, or worse, multiple flags. Continuations are described in
the first edition of Charniak, Riesbeck, and McDermott,
"Artificial Intelligence Programming," (Chapter 17, I think). That
section has been rewritten in the new edition (which Chris and
I are just now finishing).
T does indeed use continuations internally and you can make them yourself
with LAMBDA expressions. In fact I do just that when compile TLOG (logic
programming) into T. What T does not support is just the type of
continuations decribed in AI Programming, the kind that let you return to a
previous state of the computation. Doing it with LAMBDAs is not as nice,
and its supported in COMMON LISP.
You might also want to read the "LAMBDA papers," a collection of
tech reports from MIT written by Steele and Sussman in the days
when Scheme was still being invented. Steele's thesis also gives
a pretty thorough description of the continuation-passing style
(CPS), e.g., how any Lisp program can be transformed into
CPS, which permits all sorts of optimizations. "Returning" a
value means calling the continuation with that value as an
argument. The reason multiple-values (in Common Lisp) are
semantically nice is that they can (should) be viewed as a
notation/mechanism for calling the continuation with several
arguements, not just one.
Thanks for the pointers.
∂30-Oct-85 1206 @MIT-MC.ARPA:JINX@MIT-OZ Continuations
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 30 Oct 85 12:05:44 PST
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 30 OCT 85 14:03:53 EST
Date: 30 Oct 1985 14:02 EST (Wed)
Message-ID: <JINX.12155301033.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Charles Dolan <cpd@LOCUS.UCLA.EDU>
Cc: Jim Meehan <Meehan@YALE.ARPA>, scheme@MIT-MC.ARPA
Subject: Continuations
In-reply-to: Msg of 30 Oct 1985 11:37-EST from Charles Dolan <cpd at LOCUS.UCLA.EDU>
Unfortunately, I think that Common Lisp style multiple-values provide
something which cannot be conveniently obtained with explicit
continuation passing.
Consider the problem of writting a mapping procedure, MVMAP, like MAP
(previously MAPCAR) with the constraint that (MVMAP f . lists) return
as many lists of values as f returns values (assuming that f returns
the same number of values on every invocation). Then (MAP f . lists)
is equivalent to (MVMAP f . lists) if f returns a single value.
The problem writting it in continuation passing style is that f must
expect a continuation given to it by MVMAP, but then +, for example,
cannot be used since it does not expect an explicit continuation.
I agree that this can be "patched" by doing something like
(mvmap explicit->implicit (implicit->explicit +) . lists)
where EXPLICIT->IMPLICIT is the explicit continuation to MVMAP, used
to pass on the "return" value to the implicit continuation, and is defined by
(define (explicit->implicit val) val) ; Gives error if more than one value
and IMPLICIT->EXPLICIT makes a procedure, which only expects an
implicit continuation, accept an explicit continuation:
(define (implicit->explicit f)
(lambda (cont . args)
(cont (apply f args))))
but this is somewhat clumsy, especially if MVMAP were to replace MAP,
as it probably should if it were implemented.
The problem arises because in Common Lisp returning one value is not
much different from returning several, since almost all of the burden
is put on the "receiving" end (and, of course, in VALUES). By
implementing multiple values in terms of explicit continuation
passing, we make procedures which potentially "return" multiple values
(even if they happen to always "return" one) quite different from
"normal" procedures since these do not expect an explicit
continuation.
∂30-Oct-85 1351 @MIT-MC.ARPA:HUDAK@YALE.ARPA will the real current continuation please stand up
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 30 Oct 85 13:50:24 PST
Received: from yale by MIT-MC.ARPA 30 Oct 85 16:45:38 EST
Received: by Yale-Bulldog.YALE.ARPA; 30 Oct 85 15:33:19 EST (Wed)
Message-Id: <8510302033.AA12517@Yale-Bulldog.YALE.ARPA>
Received: from YALE-RING by YALE-RES via CHAOS; Wed, 30 Oct 85 15:35:25 EST
Subject: will the real current continuation please stand up
Date: Wed, 30 Oct 85 15:35:29 EST
From: Paul Hudak <Hudak@YALE.ARPA>
To: scheme@MIT-MC
Cc:
I have a question for the Scheme philosophers, which relates somewhat
to pedagogy: Why was CALL/CC designed in just the way it was? In
particular, I tend to think of CALL/CC as "providing a way to grab
the current continuation," which makes especially good sense to those
familar with denotational semantics. But then the immediate question
raised is, "why not just have a procedure CURRENT-CONTINUATION that,
when called with no arguments, returns the current continuation?"
The answer, of course, is that then no real "fork" in the processing
occurs, which brings up the following point: In a sense CALL/CC does
*not* pass the current continuation to its argument; it passes the
continuation corresponding to the point *surrounding* the call to
CALL/CC. The *real* current continuation is the one that passes control
to the functional argument to CALL/CC.
So my question is this: Has anyone considered alternate ways of
providing the CALL/CC capability? And does it make any sense at all
to use something like the CURRENT-CONTINUATION suggested above?
(I am *almost* convinced that I can't implement CALL/CC with
CURRENT-CONTINUATION, but maybe I haven't thought hard enough.)
-Paul
∂30-Oct-85 1410 JAR@MIT-MC.ARPA Continuations
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 30 Oct 85 14:09:59 PST
Date: Wed, 30 Oct 85 17:10:56 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: Continuations
To: Meehan@YALE.ARPA
cc: SCHEME@MIT-MC.ARPA, cpd@LOCUS.UCLA.EDU
In-reply-to: Msg of Wed 30 Oct 85 08:37:27 PST from Charles Dolan <cpd at LOCUS.UCLA.EDU>
Message-ID: <[MIT-MC.ARPA].698607.851030.JAR>
Let's not quibble over terminology. CPD's question is perfectly clear
and well-informed. T supports continuations like Fortran does: they
exist but aren't first-class; they can't be returned as values of
procedures. I think that when talking about continuations it's OK to
omit the qualifier "first-class," since it's usually understood, the
same way it's understood when you say "closure." It's vacuous to say
that a language has or doesn't have closures or continuations unless the
adjective first-class is assumed; therefore assume it. (Some people
will always choose to be confused.)
I think first-class continuations are generally good for the soul, and I
think it's good that the new Scheme report requires them. I've never
claimed that T was really a Scheme dialect. (Maybe one of these days it
will be.) But the question of what one legitimately does with
continuations is nontrivial. I'd like for people out there who have
real experience with them (e.g. someone from Indiana) to say something
about this.
The main problem I have with continuations is that a truly correct
implementation would dictate that a compiler cannot beta-convert in many
places where beta-conversion would otherwise be desirable. This problem
is discussed on page 92 of Steele's tech report on RABBIT.
∂30-Oct-85 1503 JAR@MIT-MC.ARPA will the real current continuation please stand up
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 30 Oct 85 15:02:08 PST
Date: Wed, 30 Oct 85 18:02:44 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: will the real current continuation please stand up
To: Hudak@YALE.ARPA
cc: SCHEME@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].698732.851030.JAR>
I think they're equipotent, if you allow a little bit of kludgery.
I take it you would define
(current-continuation)
to mean the same as
(call-with-current-continuation (lambda (c) c)) ?
Then e.g.
(let ((c (current-continuation)))
(cond ((eq? c 'a) 'b)
(else (c 'a))))
would evaluate to b.
Then I think you could just do this:
(define (call-with-current-continuation p)
(let ((c (current-continuation)))
(cond ((pair? c)
(car c))
(else
(p (lambda (val) (c (cons val nil))))))))
I think it's somewhat more natural to take
call-with-current-continuation as primitive.
∂30-Oct-85 1800 @MIT-MC.ARPA:JINX@MIT-OZ will the real current continuation please stand up
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 30 Oct 85 17:55:13 PST
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 30 OCT 85 20:33:57 EST
Date: 30 Oct 1985 20:32 EST (Wed)
Message-ID: <JINX.12155372006.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Jonathan A Rees <JAR@MIT-MC.ARPA>
Cc: Hudak@YALE.ARPA, SCHEME@MIT-MC.ARPA
Subject: will the real current continuation please stand up
In-reply-to: Msg of 30 Oct 1985 18:02-EST from Jonathan A Rees <JAR at MIT-MC.ARPA>
The main difference that I see between CALL-WITH-CURRENT-CONTINUATION
and CURRENT-CONTINUATION is that when CURRENT-CONTINUATION is used,
the continuation returned has already been invoked (namely to return
itself), thus any further (explicit) invocations are additional
invocations. In the CALL-WITH-CURRENT-CONTINUATION world this
continuation has not yet been "used". While there is no difference if
continuations are re-entrant (they can be invoked more than once),
CURRENT-CONTINUATION can only be used under this assumption.
As far as HUDAK@YALE's original question: He distinguished between the
continuation to the CALL-WITH-CURRENT-CONTINUATION invocation (outer
continuation), and the continuation to the argument (inner
continuation), but the way I see it both are the same. The
continuation-passing definition of CALL-WITH-CURRENT-CONTINUATION that
I use is:
(define (call-with-current-continuation *cont* receiver)
(receiver *cont* *cont*))
where procedures always receive an additional argument (the first)
which is the implicit continuation. Clearly then both continuations
(outer and inner) are the same. In other words, since
CALL-WITH-CURRENT-CONTINUATION reduces (tail-recurses) into its
argument, the continuations are the same.
∂30-Oct-85 1827 @MIT-MC.ARPA:HUDAK@YALE.ARPA Re: will the real current continuation please stand up
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 30 Oct 85 18:27:15 PST
Received: from yale by MIT-MC.ARPA 30 Oct 85 21:25:22 EST
Received: by Yale-Bulldog.YALE.ARPA; 30 Oct 85 21:12:27 EST (Wed)
Message-Id: <8510310212.AA00384@Yale-Bulldog.YALE.ARPA>
Received: from YALE-RING by YALE-RES via CHAOS; Wed, 30 Oct 85 20:40:10 EST
Subject: Re: will the real current continuation please stand up
Date: Wed, 30 Oct 85 20:40:11 EST
From: Paul Hudak <Hudak@YALE.ARPA>
To: Jonathan A Rees <JAR@MIT-MC>
Cc: SCHEME@MIT-MC
In-Reply-To: Jonathan A Rees <JAR@MIT-MC.ARPA>, Wed, 30 Oct 85 18:02:44 EST
I think they're equipotent, if you allow a little bit of kludgery.
...
Very nice -- although I'd call it "cleverness" rather than "kludgery."
I think it's somewhat more natural to take
call-with-current-continuation as primitive.
I can't argue with that. But it's satisfying to know that
call-with-current-continuation can be implemented with something that
in a sense is more primitive. Thanks.
-Paul
∂31-Oct-85 1024 @MIT-MC.ARPA:dyb%indiana.csnet@CSNET-RELAY.ARPA Scheme Implementation Blurb: Chez Scheme
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 31 Oct 85 10:24:31 PST
Received: from CSNET-RELAY.ARPA by MIT-MC.ARPA 31 Oct 85 13:21:54 EST
Received: from indiana by csnet-relay.csnet id ac00927; 31 Oct 85 13:18 EST
Date: Thu, 31 Oct 85 11:27:02 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: SCHEME@mit-mc.ARPA
Subject: Scheme Implementation Blurb: Chez Scheme
Implementation: Chez Scheme
Authored by: Kent Dybvig
Supported by: limited support by the author
Hardware: VAX
Operating Systems: 4.2 BSD UNIX (or ULTRIX)
Implementation: incrementally compiled to native code
Intended Use: education and research
Chez Scheme was first released earlier this year and is now
being used at about 10 universities for classes and research.
Chez Scheme supports almost all of the required and optional
features of the RRRS. The next major release (in spring or
summer 1986) will support 100% of the required features of the
standard.
In addition to the features of the RRRS, Chez Scheme provides
error and exception handling, engines, programmable cafes and
waiters (fancy read-eval-print loops), tracing and statistics-
gathering facilities, and fast-loading compiled files. Chez
Scheme provides floating point numbers, arbitrary-precision
ratios, and arbitrary-precision integers, but no imaginary
numbers at this time.
Bruce Smith of UNC and myself have written a book on Scheme
that is scheduled to be published in the spring. This book
serves as the reference manual for Chez Scheme and is sent
in draft form with Chez Scheme distributions.
Chez Scheme's biggest claim to fame is the speed and size of
its implementation. It outperforms Franz Lisp and DEC Common
Lisp on most programs, but the initial core image is less than
500K bytes, about half of which is read-only and sharable.
Sue Dybvig and myself have started a small consulting business,
named Cadence Research Systems, primarily for the purpose of
distributing and supporting Chez Scheme. We charge a license
fee to cover costs of distribution. The license fee per site
is $400 for US colleges and universities and $1000 for companies
who will use the system for research and education only.
For the license forms and ordering information, contact:
Kent Dybvig
Cadence Research Systems
620 Park Ridge Road
Bloomington, IN 47401
812/333-9269
You can also reach me during the day at 812/335-8653.
Kent Dybvig
dyb.indiana@csnet-relay
∂01-Nov-85 1351 @MIT-MC.ARPA:HUDAK@YALE.ARPA Re: will the real current continuation please stand up
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 1 Nov 85 13:51:41 PST
Received: from yale by MIT-MC.ARPA 1 Nov 85 16:50:27 EST
Received: by Yale-Bulldog.YALE.ARPA; 1 Nov 85 14:46:13 EST (Fri)
Message-Id: <8511011946.AA01493@Yale-Bulldog.YALE.ARPA>
Received: from YALE-RING by YALE-RES via CHAOS; Fri, 1 Nov 85 14:47:57 EST
Subject: Re: will the real current continuation please stand up
Date: Fri, 1 Nov 85 14:47:58 EST
From: Paul Hudak <Hudak@YALE.ARPA>
To: Bill Rozas <JINX%MIT-OZ@MIT-MC>
Cc: SCHEME@MIT-MC
In-Reply-To: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>, 30 Oct 1985 20:32 EST (Wed)
As far as HUDAK@YALE's original question: He distinguished between
the continuation to the CALL-WITH-CURRENT-CONTINUATION invocation
(outer continuation), and the continuation to the argument (inner
continuation), but the way I see it both are the same.
I see your point. I guess it all depends on how one defines
"continuation." I was interpreting it as "what happens next,"
so in your definition:
(define (call-with-current-continuation *cont* receiver)
(receiver *cont* *cont*))
what happens next is a call to receiver, so the (eventual) call to
*cont* is "delayed." On the other hand, in:
(define (current-continuation *cont*)
(*cont* *cont*))
the current continuation is called immediately (i.e., passed to itself),
which is of course what you pointed out in the first part of your message.
-Paul
∂08-Nov-85 1809 @MIT-MC.ARPA:BARTLEY%ti-csl.csnet@CSNET-RELAY.ARPA Syntactic extensions to Scheme
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 8 Nov 85 18:09:06 PST
Received: from CSNET-RELAY.ARPA by MIT-MC.ARPA 8 Nov 85 12:49:59 EST
Received: from ti-csl by csnet-relay.csnet id ad09069; 8 Nov 85 12:44 EST
Date: 7 Nov 1985 1112-CST
From: David Bartley <Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Syntactic extensions to Scheme
To: RRRS-Authors@mit-mc.arpa
cc: Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA
Received: from csl60 by ti-csl; Fri, 8 Nov 85 10:09 CST
One of the issues shunted aside a year ago was the question of how to
provide users with the ability to make syntactic extensions. I think
it would be fruitful to have some calm discussion on this topic in the
RRRS-AUTHORS mailing list. I doubt if we're ready to standardize on
any particular approach, but it would be helpful if we all knew more
about the alternatives and people's experiences with them.
I'm particularly interested in experiments such as T's with extensive
support for syntax tables. What are their strengths and weaknesses?
What do they cost in terms of compiler or runtime complexity? Do
users make effective use of them? How flexible are they---would they
suffice for major language changes?
Should syntactic extensions be specified entirely in source terms, or
should the user have access to internal representations? Should
simple source-to-source optimizations be communicated to the compiler
using the same mechanism, or is something else more appropriate?
Regards,
David Bartley
-------
∂12-Nov-85 1334 @MIT-MC.ARPA:OXLEY%ti-csl.csnet@CSNET-RELAY.ARPA PC Scheme Implementation Information
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 12 Nov 85 13:34:33 PST
Received: from CSNET-RELAY.ARPA by MIT-MC.ARPA 12 Nov 85 16:33:12 EST
Received: from ti-csl by csnet-relay.csnet id ae14406; 12 Nov 85 16:17 EST
Date: 12 Nov 1985 1035-CST
From: Don Oxley <OXLEY%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: PC Scheme Implementation Information
To: Scheme@mit-mc.arpa
Received: from csl60 by ti-csl; Tue, 12 Nov 85 12:48 CST
The following description of TI's PC Scheme product is a (belated)
response to Jonathan's request for implementation information:
Implementation: PC Scheme
Developed by: Texas Instruments Computer Science Lab
Supported by: Texas Instruments Digital Systems Group
Hardware: TI Professional and TI Business-Pro Computers,
IBM PC, PC/XT, PC/AT and IBM compatibles
Operating Systems: MS(tm)-DOS 2.1 (PC-DOS) or better (at least 320K, dual
floppy)
Price/Availability: List price - $95, available in December 1985
Implementation: Incrementally compiled to byte-codes
Intended Use: Education, research, and support of AI software on PCs
PC Scheme is an implementation of Scheme for the TI Professional
Computer and IBM(r) Personal Computer families. The product
consists of an optimizing compiler, a byte-code interpreter, extensive
run time support, an interactive, display-oriented editor, a language
reference manual, and a user's guide. The system was developed on the
TI Professional Computer in Scheme itself, with critical run time
routines coded in C and assembly language for increased performance.
PC Scheme provides all the essential and most of the optional features
of the Revised Revised Report on Scheme. It fully supports the
dialect used in the book "Structure and Interpretation of Computer
Programs" by Abelson and Sussman as well as many extensions developed
at Indiana University, MIT, and TI. These include first-class engines
and environments and an experimental, object-oriented programming
system with dynamic multiple inheritance called SCOOPS. Data type
support includes symbols, lists, vectors, strings, fixnums, bignums,
flonums (64 bit IEEE floating point), characters, closures,
continuations, environments, and I/O ports.
Evaluation is based on incremental compilation to byte-coded "virtual
machine" code which is emulated using threaded code techniques.
Informal benchmarks, including some of the Gabriel set, show PC Scheme
programs to be about 3-10 times faster than interpreted IQLISP(tm) and
2-4 times faster than interpreted Golden Common LISP(tm).
PC Scheme is oriented primarily towards compilation and fast execution
rather than extensive source-level debugging. However, it does
provide trace and breakpoint facilities and an interactive Inspector
with commands to display and manipulate call stack frames and lexical
environments, edit variable bindings, trace back through a chain of
procedure calls, and evaluate expressions in the environment of a
breakpoint. All user-correctable errors trap to the Inspector.
The display-oriented editor supplied with PC Scheme is a subset of
EDWIN, a version of EMACS written by the Scheme project at MIT and
adapted to PC Scheme by TI. 512K bytes of RAM are required to use
EDWIN.
Other PC Scheme run time support includes windowed screen input/output,
graphics, a pretty-printer, and an editor of in-memory list structures.
Compiled files can be converted to a "fast-load" format to speed up load
times. Files containing variable definitions can be "autoloaded" on
demand. A Winchester disk minimizes the inconvenience of autoloading,
but is not required.
Documentation includes a 286-page language reference manual and a
93-page user's guide. Neither manual attempts to be a tutorial manual
for Scheme itself.
PC Scheme is being used extensively within Texas Instruments and is
the basis for future releases of TI's PC-based AI products, including
Arborist (tm) and the Personal Consultant Plus (tm). It is currently
in use at approximately 25 universities in various settings (classes,
experimentation, evaluation).
PC Scheme may be ordered beginning November 15 for shipment in
December. To order, write to Texas Instruments, 12501 Research Blvd.,
MS 2151, Austin, TX 78759 and ask for TI Part number #2537900-0001.
You may also order by telephone using MasterCard or VISA by calling
1-(800)-TI-PARTS.
Questions or comments on the product may be directed to the address
given above. We also welcome less formal technical questions and
comments, which may be directed via CSNET to Oxley@TI-CSL.
--Don
-------
∂12-Nov-85 1905 JAR@MIT-MC.ARPA test message
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 12 Nov 85 19:05:00 PST
Date: Tue, 12 Nov 85 22:04:47 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: test message
To: RRRS-AUTHORS@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].716206.851112.JAR>
Please ignore.
(I want to make sure that sending to this list actually works.)
∂13-Nov-85 1618 JAR@MIT-MC.ARPA a modest backquote proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 13 Nov 85 16:11:54 PST
Date: Wed, 13 Nov 85 19:13:47 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: a modest backquote proposal
To: RRRS-AUTHORS@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].716925.851113.JAR>
I would like to propose the following: we should agree on a standard
internal form for backquote forms. That is, if a portable Scheme
program does (READ) and the available input is e.g. "`(FOO ,BAR (A ,@BAZ
B))", or if the expression '`(FOO ...) occurs in the program itself, the
program should be able to detect the fact that it has its hands on a
backquoted form, and take it apart and do something meaningful with it.
I would like the situation to be exactly the same as that of the 'FOO
syntax, where we know e.g. that (CAR ''FOO) => QUOTE and (CADR
''FOO) => FOO.
Just to make this concrete, here is one form that this proposal could
take: we could say that '`(FOO ,BAR (A ,@BAZ B)) is semantically
identical to '(#!QUASIQUOTE (#!UNQUOTE BAR) (A (#!SPLICE BAZ) B)). We
need not specify what the objects #!QUASIQUOTE etc. are; they could be
symbols or special constants. All that's needed is e.g. that (EQ?
'#!UNQUOTE '#!UNQUOTE) will work, that is, you get an EQ object each
time you read that syntax - the same situation as with symbols.
Thus we would have: (CAADR '`(FOO ,BAR)) => #!UNQUOTE, and so on.
Note that this implies nothing about implementation except that the
"expansion" of backquote forms into calls to LIST etc., if indeed that's
how it's done, isn't generally done at "read time," but rather at
"compile time" or "macro expansion time". (Expansion at read time would
of course be correct if the file was being read by LOAD and the
backquote form was known to occur outside of a QUOTE special form, etc.
All that's important is behavior detectable by user code.) We would
just need to add #!QUASIQUOTE as a new special form or macro. I know
that this would be a trivial change to MIT Scheme and T, for example,
since they already work this way.
Now here's the rationale:
(1) This removes a wart in the meaning of READ and QUOTE. Without this,
there is absolutely nothing in the report which guarantees that reading
or quoting backquote forms is even legal, much less that it has a
predictable meaning. But the absence of a representation for backquote
forms is the only obstacle to this. Given such a representation, we
have a very nice general syntactic property: any sequence of terminals
which may be derived from the the <expression> nonterminal may also be
derived from the <datum> terminal. That is, READ and QUOTE give
standard representations of programs as data.
(2) As a consequence, it will be possible to write portable
interpreters, compilers, cross-compilers, macroexpanders,
cross-reference programs, pretty-printers, readers, and so forth, which
will work on any program written in RRRSS, even those that use
backquote.
It seems to me that the desirability of being able to write
meta-programs would far outweigh any arguments about implementation
preemption. I guess I might be asking some of you to modify your
implementations (e.g. some implementations might be expanding at read
time), so there's a tiny bit of work involved in this, but I think it
would generally be a very easy change for most implementors to make.
(By the way, there is a subtlety involved in expanding nested backquote
forms AFTER read time which I'll explain under separate cover if someone
asks me to.)
The fact that Common Lisp doesn't have this feature has made it
difficult to write a portable implementation of RRRSS in Common Lisp.
To do it right I'll have to define my own backquote read macro and
expander, which is silly of course. The situation is worse in Scheme,
which doesn't have read macros - one would actually have to write a
reader in order to write any portable meta-program.
[Unrelated footnote: LOAD and EVAL are equipotent; either can be
implemented in terms of the other. RRRS has one but not the other.]
∂14-Nov-85 1020 JAR@MIT-MC.ARPA Syntactic extensions to Scheme
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 14 Nov 85 10:17:09 PST
Date: Thu, 14 Nov 85 13:19:18 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: Syntactic extensions to Scheme
To: Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MIT-MC.ARPA
In-reply-to: Msg of 7 Nov 1985 1112-CST from David Bartley <Bartley%CSL60%ti-csl.csnet at CSNET-RELAY.ARPA>
Message-ID: <[MIT-MC.ARPA].717960.851114.JAR>
Date: 7 Nov 1985 1112-CST
From: David Bartley <Bartley%CSL60%ti-csl.csnet at CSNET-RELAY.ARPA>
... I'm particularly interested in experiments such as T's with extensive
support for syntax tables.
You ask hard questions. Therefore this message is very long.
Before answering the questions, I'll summarize how T syntax tables work:
The evaluator and compiler each take a syntax table argument. A syntax
table maps symbols to objects called "syntax descriptors". A syntax
descriptor is basically either a primitive token, for primitive special
forms like QUOTE and LAMBDA, or it's a macro expansion function. Syntax
descriptors print as #[Syntax ...], where ... somehow identifies the
descriptor (name or whatever).
When the compiler processes a form whose car is a symbol, the first
thing it does is look up the symbol in the syntax table. If there is an
entry in the table, say (syntax-table-entry table 'foo) => #[Syntax
BAR], the form is processed as if the form (#[Syntax BAR] ...) had been
seen. When a form whose car is a syntax descriptor is processed, the
appropriate thing happens; if the descriptor is a macro expander, the
form is expanded; if it's primitive, the form is interpreted as a QUOTE
or LAMBDA or whatever expression.
Users can create syntax tables, fetch and store entries in them, and
pass them to the evaluator or compiler. A macro (macro-expander ...)
creates a descriptor for a macro expander. If no syntax table argument
is supplied to EVAL or LOAD, a syntax table is obtained from the
environment argument by accessing the value of a lexical environment
variable with a special internal name (let's suppose the name is
&&syntax-table&&; in principle it's something untypable). There is
a special form DEFINE-SYNTAX which basically does a RUNTIME side-effect
of storing a descriptor into &&syntax-table&&. (DEFINE-SYNTAX has
no effect at compile time.)
In addition, DEFINE-LOCAL-SYNTAX defines a macro local to a file or
expression, analogous to MACROLET in Common Lisp. This has no effect at
runtime. (DEFINE-MACRO (FOO ...) ...) is a horrible dual-purpose form
which is the same as
(BEGIN (DEFINE-SYNTAX (FOO ...) ...)
(DEFINE-LOCAL-SYNTAX (FOO ...) ...)).
End of summary, now for the questions.
What are their strengths and weaknesses?
Strength: the ability to make "absolute references" to standard syntactic
forms - i.e. (#[Syntax LAMBDA] (X) (+ X 5)) - is a boon to embedded
incompatible language implementation. E.g. suppose you wanted to define
a syntax table where DEFINE was a macro which expanded into something
which wanted to use the usual Scheme DEFINE. It wouldn't work to do
(define-syntax (define ...) `( ... (define ...) ...))
since this is circular. But you could do
(define-syntax (define ...) `( ... (#[Syntax DEFINE] ...) ...))
where #[Syntax DEFINE] denotes the standard syntax descriptor for
DEFINE.
This is how I was able to write implementations of RRRSS and even a sort
of bastard Common Lisp in T, even though there were multiple
incompatibilities. And because everything is scoped, one environment's
macros aren't seen in different environments, so one can easily debug
programs different parts of which are written using completely
different syntax.
The standard system macros all do the absolute reference trick, and the
effect is that a macro can expand a form into a new form which uses a
different macro, without having to worry about whether the macro in the
expansion was defined in the syntax table being used to process the
expansion. Thus descriptors can be moved from one syntax table to
another without worrying too much about how they're defined - they act
almost like closures. (Note that this problem doesn't come up in Common
Lisp because one "closes" over an environment (package) at read time.
Macros in Scheme have to be more complicated since Scheme did the right
thing with symbols.)
Weaknesses: there are the usual kinks. Best to give an illustration.
Suppose a Scheme program (file) contains the following forms:
(define-macro (foo form) (bar form))
(define (bar form) `(#[syntax lambda] () (baz ,form)))
(define (baz obj) (cons (cdr obj) (car obj)))
((foo (cons 'a 'b)))
If your model of macro expansion is that it's part of what the evaluator
does, then this "works:" the last form evaluates to (b . a). This is
the simplest explanation of what macos do, and it's what I think most
naive users believe happens. Indeed it is what happens in many Lisp
interpreters.
However, the code is obviously sensitive to what happens at compile time
and what happens at run time. Presumably the compiler does not load the
file. So when the FOO form gets expanded by the file compiler, the
expander tries to call BAR, which is undefined.
T is badly engineered in the sense that this code will run interpreted
and not compiled. This is because the environment in which the macro
expansion function is closed is the same as the one in which the
expansion will run. (Common Lisp has the same problem.) Users should
have to work much harder than this to find inconsistencies like this. A
small improvement would be if LOAD "macroexpanded" the whole file before
running any of it; then FOO would be undefined at expand time. But this
isn't a very general solution. What if the forms occur in different
files? What if the code is reloaded into the same environment - will it
work the second time, using the definition of FOO from the first LOAD?
In the best of all possible worlds, macros and the auxiliary functions
they call to perform expansions should only have to exist for the
purposes of compilation (and EVAL, debugging, etc.); at runtime they can
go away or be garbage collected. (Consider using a Scheme compiler to
build a small stand-alone system which wants to run in minimal address
space. Expansion functions are superfluous at runtime.) This suggests
that macros should always inhabit separate modules in their own separate
environments. These modules can be loaded for compilation purposes, if
a client requests, but needen't exist at runtime. Users should have to
go to the extra trouble of announcing that they are defining a
compilation-support module to cause DEFINE-SYNTAX itself to become
available at all.
I haven't even talked about the problem of the scoping of BAZ. As it
is, any client of the FOO macro must know that the variable BAZ occurs
free in the expanded form, and suffer the consequences. I don't see any
way around this if out-of-core compilation is going to work. A listing
of what variables are free (in principle one needs at most 1 such) must
simply be part of the documentation of FOO. (One can play tricks with
system primitives like CAR, but the problem remains when the expansion
needs a user-defined function.)
Whew... obviously this is much too complicated. I have sympathies for
the trstricted Indiana approach to macros, although I'm not sure it gets
around all the various problems, and I would resist giving up the
ability to write arbitrary expansion procedures. But I am certainly not
asking anyone to adopt T's syntax mechanism, since the specification is
so bug-ridden.
What do they cost in terms of compiler or runtime complexity?
In spite of all this wind, the implementation is very straightforward.
One just puts hooks into EVAL and the compiler in the right place, and
passes the syntax tables around as appropriate.
Do users make effective use of them?
As long as macros exist, users will abuse them. But I think they have
their place, and a small number of people know how to use them well. It
has been suggested that a licensing agency be established.
As far as syntax tables go, I don't know of anyone who has done anything
with them quite as hairy as what I've described, but I think that the
people who exploit multiple environments (there aren't many) implicitly
use the fact that macros get scoped appropriately; they know there won't
be name conflicts, the same way they know that there won't be name
conflicts for variables.
How flexible are they---would they suffice for major language changes?
I think what I said above about embedded languages answers this for the
most part - in the affirmative. Clearly they wouldn't be effective e.g.
to change scoping or evaluation order rules, but they work well
to change the meaning of (LAMBDA ...).
Should syntactic extensions be specified entirely in source terms, or
should the user have access to internal representations?
I have a running argument with the MIT Scheme folks about this; I think
that Scheme makes a perfectly good representation for programs. There
are some scoping problems to be addressed, e.g. any macro expander
which wants to understand anything about a subexpression must know what
syntax table the subexpression is to be interpreted relative to, but as
long as some convention is established (there are a couple of
alternatives) and programmers are made aware of these issues, I don't
think we need to go to the trouble of defining new data types for
representing programs. That would be very complicated and there'd be
little hope of making the interface portable.
Should simple source-to-source optimizations be communicated to the
compiler using the same mechanism, or is something else more
appropriate?
Definitely not. I'm not sure that users should ever specify
optimizations to a compiler; perhaps it would be acceptable if the
compiler had some mechanism by which it could prove the correctness of
such transformations before deciding it was okay to do them. Also, the
situation with free variables can be very complicated. But in any case,
just for pedagogical reasons one shouldn't do anything to lead users to
believe that macros and procedures have any similarites at all. It's
bad enough that they are syntactically similar.
[By the way, even though T and MIT Scheme agreed some years back that
(LET ((IF LIST)) (IF 1 2 3)) should evaluate to 2 , and I used to think
this was the only acceptable semantics, now I'm not convinced that
this is the right thing; I think Kent Pitman has a coherent semantics
which would allow it to evaluate to (1 2 3), without sacrificing
compilability or purity. But I'll let him explain that. I'm not
convinced he's right either.]
∂14-Nov-85 1559 @MIT-MC.ARPA:JINX@MIT-OZ Syntactic extensions to Scheme (long message)
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 14 Nov 85 15:59:18 PST
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 14 NOV 85 18:36:00 EST
Date: 14 Nov 1985 18:28 EST (Thu)
Message-ID: <JINX.12159281629.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Jonathan A Rees <JAR@MIT-MC.ARPA>
Cc: Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA, RRRS-AUTHORS@MIT-MC.ARPA
Subject: Syntactic extensions to Scheme (long message)
In-reply-to: Msg of 14 Nov 1985 13:19-EST from Jonathan A Rees <JAR at MIT-MC.ARPA>
Just a few comments explaining a little about how syntax tables in MIT
Scheme currently work.
Scheme programs are translated into SCode (1) before either the evaluator
or the compiler touch them, thus macros do not have to be handled by
either but by this translator, which we call the syntaxer.
The syntaxer has one required argument (the expression to translate to
Scode), and two optional arguments. One of them is the syntax table
to use in the translation. The other is the syntax environment, which
is the environment in which to evaluate any expressions which must be
evaluated at syntax time, e.g. lambda expressions which result in
macro expanders.
If these arguments are not given explicitly, default values are used.
These default values can be manipulated with the procedures
current-syntax-table, set-current-syntax-table!, with-syntax-table,
and the analogous ones for syntax environments.
There are some operations defined on syntax tables:
(syntax-table-define <table> <symbol> <translator>)
(syntaxt-table-ref <table> <symbol>) -> <translator>
and some less interesting ones.
A translator is supposed to translate an s-expression into Scode, but
source to source macro facilities are also provided. Some syntax time
syntactic sugar is also provided, thus
(define-syntax <name-of-special-form> <translator>)
Does a syntax-time syntax-table-define on the current syntax table,
(let-syntax ((<name> <translator>)...) . <expresssions>)
is analogous to LET, creating a new syntax table,
(using-syntax <syntax-table> . <expressions>)
is the syntax-time with-syntax-table, and
(macro <formals> . <body>)
is analogous to LAMBDA but "returns" a source level translator, similar
in effect to traditional Lisp Macros, except that they are expanded at
syntax time.
We do not provide "reader" syntax for obtaining translators or
denoting expansions, we instead invoke them explicitely to insure that
the correct expander is used. Thus if WHILE is defined by
(define-syntax while
(macro (pred . exps)
`(let ((pred (lambda () ,pred))
(body (lambda () ,@exps)))
(letrec ((loop
(lambda ()
(if (pred)
(begin (body) (loop))))))
(loop)))))
The following 2 definitions have different effects, depending on
whether WHILE is redefined
(define-syntax for
(macro (index low high . exps)
`(let ((,index ,low))
(while (<= ,index ,high) ; Dynamic use of WHILE
,@exps
(set! ,index (1+ ,index))))))
(define-syntax for
(let ((while-xform ; The translator
(syntax-table-ref (current-syntax-table) 'WHILE)))
(macro (index low high . exps)
`(let ((,index ,low))
,(while-xform ; Static use
`(while (<= ,index ,high)
,@exps
(set! ,index (1+ ,index))))))))
Note that the traditional Lisp DEFMACRO can be obtained by
(define-syntax defmacro
(macro (pattern . body)
(let ((the-name (car pattern))
(the-translator `(macro ,(cdr pattern) ,@body)))
`(begin
(syntax-table-define (current-syntax-table) ; Runtime
',the-name
,the-translator)
(define-syntax ,the-name ,the-translator))))) ; Syntax (compile) time
In the example that Jonathan gives we would also have problems, since
the default is that the current syntax environment is the same as the
read-eval-print loop environment, thus the code would "work"
interpreted but not compiled. Changing current syntax environment is
a possibility which we should probably do.
We do not object to using Scheme for syntactic extensions. As a
matter of fact, I never write syntactic expressions which do not end
up being macros (after grabbing the appropriate stuff), only the
bottom level (the core special forms) translate to Scode, but there is
no reason not to make this an option in our system.
I agree with Jonathan in that syntax should not be used for
optimizations, and also in that lambda-bound names should take
precedence over syntactic items. Thus in his binding-of-IF example, I
think that '(1 2 3) should be returned. We probably will change our
system to do this, but we have not yet done that.
(1) Scode can be thought of as a small, explicit version of Scheme,
where every expression is an explicit special form, thus it has
VARIABLE and COMBINATION explicit special forms.
∂14-Nov-85 2150 @MIT-MC.ARPA:CPH@MIT-OZ Syntactic extensions to Scheme
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 14 Nov 85 21:50:40 PST
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 15 NOV 85 00:41:14 EST
Date: Fri, 15 Nov 1985 00:37 EST
Message-ID: <CPH.12159348700.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: Jinx%MIT-OZ@MIT-MC.ARPA
Cc: JAR@MIT-MC.ARPA, Bartley%CSL60%TI-CSL.CSNet@CSNET-RELAY.ARPA,
RRRS-Authors@MIT-MC.ARPA
Subject: Syntactic extensions to Scheme
I would like to point out that I believe that MIT Scheme has more
power in its syntactic extension mechanism than is necessary or
desirable. In particular, I have found that there are only two
general scenarios for macro use (please correct or expand on this):
----------------------------------------------------------------------
The first case is the local use of a macro to eliminate syntactic
repetition. For example, suppose one wanted to say something like:
(define <var1> (lambda (x) (vector-ref x 1)))
(define <var2> (lambda (x) (vector-ref x 2)))
...
(define <varn> (lambda (x) (vector-ref x n)))
in this case a local macro could be used profitably, as in (MIT
Scheme):
(let-syntax ((make-ref
(macro (var index)
`(DEFINE ,var
(LAMBDA (X)
(VECTOR-REF X ,index))))))
(make-ref <var1> 1)
(make-ref <var2> 2)
...
(make-ref <varn> n))
The combination of LET-SYNTAX and MACRO used here gives sufficient
power to do local definitions like this, and also to have defined the
macro somewhere else, say, and access it later by name, as in
(let-syntax ((make-ref the-make-ref-macro)) ...)
Note that this makes no explicit use of the concept of syntax table,
despite the fact that it is implemented using that mechanism.
The issue of what environment in which the binding value of the
LET-SYNTAX form is evaluated is important here, and in fact is
specified externally by passing an explicit environment to the syntax
expander program as described by Jinx earlier. But in practice, local
macros such as these require only the normal global environment, and
any local procedures can be defined using something like:
(let-syntax ((make-ref
(let ()
(define ...)
(define ...)
(macro ...))))
...)
A particular difference between this mechanism and the DEFINE-SYNTAX
mechanisms described by JAR and Jinx is that, psychologically, it is
less likely that someone would be confused about what environment and
at what time the binding value of the LET-SYNTAX would be evaluated.
Such confusion is still possible, but I believe it is easier to think
of the binding value as being separate from the rest of the code than
in the case where the macro definition appears as just another top
level definition.
----------------------------------------------------------------------
The second case is the definition of a whole language of syntactic
extensions, which will be used over a large body of code. An example
of this usage is my recent implementation of the Edwin editor, in
which a number of macros for defining editor commands, variables, and
modes were used throughout much of the source code. I believe that
this case is the one that normally provides much of the trouble.
I have taken the following conservative approach (I suspect that this
will draw some good criticism; my only response is that it has proven
adequate to date):
* I have assumed that each type of syntactic "language" will
correspond directly to a particular syntax-table. The
single-inheritance mechanism used by syntax tables is sufficient for
many needs.
* I have assumed that definition of the syntactic extensions is
syntactically separate from their use. This implies that the syntax
defined by the extensions is NOT available for use at the time that
the definitions of the extensions are processed by the syntactic
expander. (I hope that this wording is sufficiently general that it
does not restrict my comments to MIT Scheme's implementation.)
In practice, this means the following thing: that the syntax
definitions reside in a separate file(s) from the source code that
refers to them, and that the definitions do not become effective until
the file(s) is loaded.
Here is an example of how one would define some syntax:
(define edwin-syntax-table
;; This means the parent of this syntax table is the "normal" one.
(make-syntax-table system-global-syntax-table))
(syntax-table-define edwin-syntax-table 'define-command
(macro ...))
(syntax-table-define edwin-syntax-table 'define-variable
(macro ...))
etceta. Supposing the above expressions to be evaluated in some
environment, then the following code could be evaluated (or compiled
without evaluation):
(using-syntax edwin-syntax-table
(define-command ("↑R Forward Character" argument)
...)
(define-variable "Comment Multi Line"
...)
...
)
The major advantage of using this approach is that the scoping
problems associated with macros are sidestepped, since the
environments in which everthing happens are eval-time environments,
rather than syntax-time environments. Also, the confusion caused by
mixing syntactic and semantic definitions in the code is eliminated.
It can (easily) be argued that this separation is a drawback as well.
I think that this is more a problem of presentation than anything
else. In particular, given the standard file-oriented methods of
maintaining systems, there is only one ordering or definitions, which
applies for both editing and evaluation. More sophisticated systems,
which I believe many people are now developing, would allow the
editing presentations to be separate from the evaluation order.
----------------------------------------------------------------------
In summary, I think that the DEFINE-SYNTAX and DEFINE-MACRO mechanisms
in both T and MIT Scheme are not particularly useful, and in fact are
confusing. Their convenience I believe to be dubious, although I will
understand if there is disagreement on this point. I do not see that
they add any real power that is not available in the cases I have
outlined above through the other mechanisms I describe.
In passing, I would like to note that I DO NOT believe that scoping of
syntactic keywords should be related to scoping of environment
variables. I think that the only reason that this has ever been
considered a reasonable idea is because of the (perhaps regrettable)
choice to make the notation used for syntactic forms and combinations
identical. However, I would be curious to see if KMP's semantics
sheds new light on this issue.
The other issue, about the use of SCode, is not so clear. In general,
I have tried to assume that syntactic extensions map from one domain
to another. Assuming that the two domains are separate is a
generality that turns out to have advantages in implementation, as it
allows the use of SCode, while not precluding purely source-to-source
macroexpansion, nor T's method of "absolute special forms". One of
the examples that Jinx presented violated this principle (see the use
of WHILE-XFORM in the second example). I am not really sure how to
handle this problem, but the separation of the domain and range of the
syntax mapping seems like a good principle to start with.
∂15-Nov-85 1251 JAR@MIT-MC.ARPA testing, testing, ...
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 15 Nov 85 12:50:52 PST
Date: Fri, 15 Nov 85 15:57:41 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: testing, testing, ...
To: SCHEME@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].719559.851115.JAR>
Several people have wondered whether they are still on the list. This
message is intended to confirm that y'all still are. The two most
recent messages were:
Date: 12 Nov 1985 1035-CST
From: Don Oxley <OXLEY%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: PC Scheme Implementation Information
Date: Fri, 1 Nov 85 14:47:58 EST
From: Paul Hudak <Hudak@YALE.ARPA>
Subject: Re: will the real current continuation please stand up
Don Oxley's message may have been lost (although I've never before known
MC's mailer to lose a message); I'll re-send it if I get deluged with
reports of non-receipt.
∂17-Nov-85 1547 @MIT-MC.ARPA:linus!ramsdell@mitre-bedford.ARPA Stream command processing (long message)
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 17 Nov 85 15:47:38 PST
Received: from mitre-bedford.ARPA by MIT-MC.ARPA 17 Nov 85 18:42:26 EST
Full-Name:
Organization: The MITRE Corp., Bedford, MA
Received: by linus.RESEARCH (4.12/4.7)
id AA26603; Fri, 15 Nov 85 15:06:32 est
Date: Fri, 15 Nov 85 15:06:32 est
From: John D. Ramsdell <linus!ramsdell@mitre-bedford.ARPA>
Posted-Date: Fri, 15 Nov 85 15:06:32 est
Message-Id: <8511152006.AA26603@linus.RESEARCH>
To: scheme@mit-mc.ARPA
Subject: Stream command processing (long message)
While I am an avid fan of Scheme, I find myself frustrated by how
difficult it is to program some stream processing tasks in Scheme
compared with the difficulty of programming the same tasks in UNIX.
Your typical UNIX hacker can whip together some concoction of awk, grep,
sed, yacc, etc. to solve these kinds of problems very quickly. But it
is quite a pain in Scheme. Even more painful is the fact that it is
very hard to use someone else's stream processing programs.
I would like to propose having two standard top level environments for
Scheme. One is the one we all know and love, and the other would be the
stream command processor (SCP). This top level environment would map a
stream like syntax into a simple composition of Scheme functions. The
map would follow a simple convention, so that inexperienced users could
easily modify or creat new functions to be used in the composition.
I have no suggestion as to the particular syntax to be used; I will use
a UNIX like syntax with no implied endorsement. I will give an example
of a simple map from this syntax to compositions of Scheme functions
using continuation streams (CSTREAMS). The continuation is not the same
one you get when you use call-with-current-continuation. Cstreams are
defined by:
; Continuation streams are procedures of one argument
; which is the procedure's continuation.
; A continuation is a procedure of two arguments,
; a stream element, and a the next stream.
; cstream = (lambda (continuation)
; Compute element and next-cstream.
; (continuation element next-cstream))
A port is turned into a cstream with:
(define (read-cstream port)
(lambda (c)
(c (read port) (read-cstream port))))
and a cstream is turned into something that works as an argument to
call-with-output-port using:
(define (print-cstream cstream)
(lambda (port)
(letrec
((continuation
(lambda (element cstream)
(if (ecse? element)
'print-done
(begin
(print element port)
(cstream continuation))))))
(cstream continuation))))
Cstream manipulation functions have the signature:
(lambda (input-cstream . arguments) ...) ==> output-cstream.
For example, the cstream mapping function looks like:
; => a cstream that results from mapping elements of cstream
; with a procedure of one argument.
(define (map-cstream cstream procedure)
(letrec
((next-cstream
(lambda (cstream)
(lambda (c)
(cstream
(lambda (element cstream)
(if (ecse? element)
(ecs c)
(c (procedure element) (next-cstream cstream)))))))))
(next-cstream cstream)))
The SCP would translate a command that looks like
map-cstream list <lists.scm >more-parens.scm
into the expression
(call-with-output-file
"more-parens.scm"
(map-cstream
(call-with-input-file
"lists.scm"
read-cstream)
list))
For a more complex example, SCP would translate the following:
filter-cstream symbol? <lists.scm | map-cstream list >single-level-list.scm
into
(call-with-output-file
"single-level-list.scm"
(filter-cstream
(map-cstream
(call-with-input-file
"lists.scm"
read-cstream)
list)
symbol?))
The set of stream functions are easily extended by writting functions that
expect a cstream for their first argument and return a cstream.
I am not particularly attached to my representation of streams, and the
streams in Sussman and Abelson's book would also do the trick. I am
most interested in an commonly aggreed upon stream processing system
that encourages the interchange of stream functions, just as the Revised
Revised Report on Scheme encourages interchange of Scheme functions.
Then Scheme hackers will definitely be kings of stream processing.
John
Here is some code to play with:
-----------
;;; -*- Mode: LISP -*-
; Continuation Streams.
; Continuation streams are procedures of one argument
; which is the procedure's continuation.
; A continuation is a procedure of two arguments,
; a stream element, and a the next stream.
; cstream = (lambda (continuation)
; Compute element and next-cstream.
; (continuation element next-cstream))
(define (error-cstream message)
(lambda (c)
c ; ignore continuation.
(error message)))
(define *ecse* ; Used to identify the empty continuation stream.
'*ecse*)
; Is the cstream element the empty cstream element?
(define (ecse? x)
(eq? x *ecse*))
(define past-end-of-cstream
(error-cstream "Read past end of cstream"))
; the empty continuation stream.
(define ecs
(lambda (c) (c *ecse* past-end-of-cstream)))
(define (ecs? cstream)
(cstream
(lambda (element cstream)
cstream ; ignore cstream.
(ecse? element))))
; => cstream which is cstream0 appended to cstream1.
(define (append-cstreams cstream0 cstream1)
(letrec
((next-cstream
(lambda (cstream)
(lambda (c)
(cstream
(lambda (element cstream)
(if (ecse? element)
(cstream1 c)
(c element (next-cstream cstream)))))))))
(next-cstream cstream0)))
; => cstream which is a fair merge of cstream0 and cstream1.
(define (interleave-cstreams cstream0 cstream1)
(lambda (c)
(cstream0
(lambda (element cstream)
(if (ecse? element)
(cstream1 c)
(c element (interleave-cstreams cstream1 cstream)))))))
; => a cstream that results from mapping elements of cstream
; with a procedure of one argument.
(define (map-cstream cstream procedure)
(letrec
((next-cstream
(lambda (cstream)
(lambda (c)
(cstream
(lambda (element cstream)
(if (ecse? element)
(ecs c)
(c (procedure element) (next-cstream cstream)))))))))
(next-cstream cstream)))
; Returns a cstream containing elements that satisfy the predicate.
(define (filter-cstream cstream predicate)
(letrec
((next-cstream
(lambda (cstream)
(lambda (c)
(cstream
(lambda (element cstream)
(if (ecse? element)
(ecs c)
(let ((next-cstream (next-cstream cstream)))
(if (predicate element)
(c element next-cstream)
(next-cstream c))))))))))
(next-cstream cstream)))
(define (list->cstream l) ; => cstream with elements in l.
(if (null? l)
ecs
(let ((element (car l))
(l (cdr l)))
(lambda (c) (c element (list->cstream l))))))
(define (cstream->list cstream) ; => list of elements in the cstream.
(let ((l '())) ; The reverse of the result is held here.
(letrec
((continuation
(lambda (element cstream)
(if (not (ecse? element))
(begin
(set! l (cons element l))
(cstream continuation))))))
(cstream continuation))
(reverse! l)))
(define (read-cstream port)
(lambda (c)
(c (read port) (read-cstream port))))
(define (print-cstream cstream)
(lambda (port)
(letrec
((continuation
(lambda (element cstream)
(if (ecse? element)
'print-done
(begin
(print element port)
(cstream continuation))))))
(cstream continuation))))
; For more, see J. D. Ramsdell "An Implementation of a Domain Calculus
; Query Language Using Continuation Streams", M84-56, MITRE Corp.
; Bedford, MA, December 1984.
∂18-Nov-85 1710 @MIT-MC.ARPA:linus!ramsdell@mitre-bedford.ARPA read-cstream fix
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 18 Nov 85 17:08:44 PST
Received: from mitre-bedford.ARPA by MIT-MC.ARPA 18 Nov 85 20:35:00 EST
Organization: The MITRE Corp., Bedford, MA
Received: by linus.RESEARCH (4.12/4.7)
id AA00913; Mon, 18 Nov 85 07:39:48 est
Date: Mon, 18 Nov 85 07:39:48 est
From: John D. Ramsdell <linus!ramsdell@mitre-bedford.ARPA>
Posted-Date: Mon, 18 Nov 85 07:39:48 est
Message-Id: <8511181239.AA00913@linus.RESEARCH>
To: scheme@mit-mc.ARPA
Subject: read-cstream fix
; read-cstream that checks for EOF.
(define (read-cstream port)
(lambda (c)
(let ((element (read port)))
(if (eof-object? element)
(ecs c) ; close port?
(c element (read-cstream port))))))
I sent out some undebuged code for read-cstream.
The above version does the correct thing for EOF.
In some applications it may be desirable to delay
the reading of the port.
(define (read-cstream port)
(let ((element (delay (read port))))
(lambda (c)
(if (eof-object? (force element))
(ecs c)
(c (force element) (read-cstream port))))))
John
∂18-Nov-85 1744 @MIT-MC.ARPA:JINX@MIT-OZ Stream command processing (long message)
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 18 Nov 85 17:43:55 PST
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 18 NOV 85 21:05:03 EST
Date: 18 Nov 1985 21:01 EST (Mon)
Message-ID: <JINX.12160358034.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: "John D. Ramsdell" <linus!ramsdell@MITRE-BEDFORD.ARPA>
Cc: scheme@MIT-MC.ARPA
Subject: Stream command processing (long message)
In-reply-to: Msg of 15 Nov 1985 15:06-EST from John D. Ramsdell <linus!ramsdell at mitre-bedford.ARPA>
Why the syntax when
For a more complex example, SCP would translate the following:
filter-cstream symbol? <lists.scm | map-cstream list >single-level-list.scm
into
(call-with-output-file
"single-level-list.scm"
(filter-cstream
(map-cstream
(call-with-input-file
"lists.scm"
read-cstream)
list)
symbol?))
∂18-Nov-85 1828 @MIT-MC.ARPA:JINX@MIT-OZ Stream command processing (long message)
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 18 Nov 85 18:28:04 PST
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 18 NOV 85 21:32:21 EST
Date: 18 Nov 1985 21:29 EST (Mon)
Message-ID: <JINX.12160363029.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: "John D. Ramsdell" <linus!ramsdell@MITRE-BEDFORD.ARPA>
Cc: scheme@MIT-MC.ARPA
Subject: Stream command processing (long message)
In-reply-to: Msg of 15 Nov 1985 15:06-EST from John D. Ramsdell <linus!ramsdell at mitre-bedford.ARPA>
filter-cstream symbol? <lists.scm | map-cstream list >single-level-list.scm
into
(call-with-output-file
"single-level-list.scm"
(filter-cstream
(map-cstream
(call-with-input-file
"lists.scm"
read-cstream)
list)
symbol?))
----------------------------------------------------------------------
Why the extraneous syntax when you can do the following
(define (>> file-name stream)
(call-with-output-file file-name stream))
(define (<< file-name)
(call-with-input-file file-name read-cstream))
(define (|| what . args)
(lambda (stream)
(apply what (cons stream args))))
(>> "single-level-list.scm"
((|| filter-cstream symbol?)
((|| map-cstream list)
(<< "lists.scm"))))
which except for the parentheses and the fact that it is left-to-right
inverted with respect to Unix is extremely close.
Sorry, but I feel that
(call-with-output-file
"single-level-list.scm"
(filter-cstream
(map-cstream
(call-with-input-file
"lists.scm"
read-cstream)
list)
symbol?))
is considerably clerarer than Unix-like syntax. It is also more
powerful since the Unix shell syntax does not allow (as far as I know)
forking or merging streams in interesting ways, both of which scheme
procedures can easily accomodate.
A portable continuation stream top level of the sort you suggest is an
afternoon's worth of work, and does not really add any power or
interesting functionality to the language, so it might as well be
provided as part of the continuation stream utilities.
∂18-Nov-85 1846 @MIT-MC.ARPA:JINX@MIT-OZ Incomplete message
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 18 Nov 85 18:46:21 PST
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 18 NOV 85 21:34:42 EST
Date: 18 Nov 1985 21:31 EST (Mon)
Message-ID: <JINX.12160363416.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: scheme@MIT-MC.ARPA
Subject: Incomplete message
Sorry. I must have spazzed and sent the message too early.
∂19-Nov-85 1327 JAR@MIT-MC.ARPA backquote proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 19 Nov 85 13:27:51 PST
Date: Tue, 19 Nov 85 16:30:10 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: backquote proposal
To: RRRS-AUTHORS@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].724256.851119.JAR>
I haven't heard any objection to the backquote proposal. Unless you
guys reply soon, it will become part of the next edition of the RRRS,
and I'll complain when my programs don't run in your implementations, so
speak up.
Small change: I think the name #!unquote-splice is a little better than
#!splice. If anyone would like to suggest better names, you're welcome
to.
Reminder: the proposal is that
`x is identical to (#!quasiquote x)
,x is identical to (#!unquote x)
,@x is identical to (#!unquote-splice x)
for the purposes of QUOTE and READ. Also, (#!quasiquote <pattern>) is a
new special form which means the same thing as `<pattern> , and within
a <pattern> one may write (#!unquote <expression>) instead of ,<expression>;
similarly for #!unquote-splice.
(Don't worry, I'll send out a proposed precise description before a new
edition of the RRRS happens.)
I have an implementation of a post-read-time #!quasiquote macro expander
(written in scheme, of course) which I'll send to anyone requesting it.
One interesting feature of it is that it does the "right" thing with
nested backquotes, that is, e.g.
(equal? '`(a ,b) ``(a ,b))
returns a true value, which isn't the case in most backquote
implementations that I know of. I don't know whether this behavior is
dictated by my backquote proposal, but it seems like desirable behavior
to me.
Jonathan
∂20-Nov-85 0901 @MIT-MC.ARPA:BARTLEY%ti-csl.csnet@CSNET-RELAY.ARPA Re: backquote proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 20 Nov 85 09:01:08 PST
Received: from CSNET-RELAY.ARPA by MIT-MC.ARPA 20 Nov 85 12:02:56 EST
Received: from ti-csl by csnet-relay.csnet id ab12530; 20 Nov 85 11:48 EST
Date: 20 Nov 1985 0943-CST
From: David Bartley <Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Re: backquote proposal
To: JAR%mit-mc.arpa@csnet-relay.arpa,
RRRS-AUTHORS%mit-mc.arpa@csnet-relay.arpa
cc: Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA
In-Reply-To: Your message of 19-Nov-85 1712-CST
Received: from csl60 by ti-csl; Wed, 20 Nov 85 10:03 CST
From JAR:
> I haven't heard any objection to the backquote proposal. Unless
> you guys reply soon, it will become part of the next edition of the
> RRRS, and I'll complain when my programs don't run in your
> implementations, so speak up.
> ...
> (Don't worry, I'll send out a proposed precise description
> before a new edition of the RRRS happens.)
Is this tongue-in-cheek or are you suggesting/presuming another round
of ``standardization'' for Scheme?
David Bartley
-------
∂20-Nov-85 1214 @MIT-MC.ARPA:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: backquote proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 20 Nov 85 12:14:03 PST
Received: from CSNET-RELAY.ARPA by MIT-MC.ARPA 20 Nov 85 15:15:56 EST
Received: from indiana by csnet-relay.csnet id ab14216; 20 Nov 85 15:03 EST
Date: Wed, 20 Nov 85 14:05:35 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: JAR@mit-mc.arpa
Subject: Re: backquote proposal
Cc: RRRS-AUTHORS@mit-mc.arpa
I like the proposed backquote change, especially since it will
allow source pretty-printers to print the original source more
accurately.
However, I do not like the use of "special objects" as special
form keywords, and would prefer to use ordinary identifier names
instead.
The reason is that, at least in my implementation, #! objects are
not symbols, and special form keywords are. I would very much
like to retain this property, for selfish reasons and because I
think it helps anyone writing program-manipulating programs to
know that special forms always begin with a symbol.
Also, it would not make sense that backquote special forms are
written with the #! if the quote special form is not.
Therefore, I propose that we use the special forms quasiquote,
unquote, and unquote-splice, dropping the #!.
Kent
∂20-Nov-85 1326 JAR@MIT-MC.ARPA backquote proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 20 Nov 85 13:24:03 PST
Date: Wed, 20 Nov 85 16:26:09 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: backquote proposal
To: dyb%indiana.csnet@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MIT-MC.ARPA
In-reply-to: Msg of Wed 20 Nov 85 14:05:35 est from Kent Dybvig <dyb%indiana.csnet at CSNET-RELAY.ARPA>
Message-ID: <[MIT-MC.ARPA].725715.851120.JAR>
Date: Wed, 20 Nov 85 14:05:35 est
From: Kent Dybvig <dyb%indiana.csnet at CSNET-RELAY.ARPA>
I like the proposed backquote change, especially since it will
allow source pretty-printers to print the original source more
accurately.
However, I do not like the use of "special objects" as special
form keywords, and would prefer to use ordinary identifier names
instead.
The reason is that, at least in my implementation, #! objects are
not symbols, and special form keywords are. I would very much
like to retain this property, for selfish reasons and because I
think it helps anyone writing program-manipulating programs to
know that special forms always begin with a symbol.
Also, it would not make sense that backquote special forms are
written with the #! if the quote special form is not.
OK, I sympathize with this. What do other people think?
Note that I never said that #!QUASIQUOTE was NOT a symbol. Things would
work just fine if it was, although it would have to print the same way
it reads.
Therefore, I propose that we use the special forms quasiquote,
unquote, and unquote-splice, dropping the #!.
I never suggested making #!UNQUOTE and #!UNQUOTE-SPLICE be special
forms, so I don't think this argument applies to them, except through
guilt by association (i.e. consistency).
I think that flagging the printed representation of these markers with
#! is good since it helps indicate that something peculiar is going on.
There is always the danger that someone will write something like
(memq z '(quote unquote quasiquote))
and that someone else will lift that code and put it into backquote
form somewhere, say
(let ((form `(cond ((memq z '(quote unquote quasiquote)) ,value))))
(compute form))
and then get the error message "QUASIQUOTE unbound variable" and wonder
what on earth happened. This violation of referential transparency is
unavoidable with non-local features like backquote, but the #!'s help
mitigate it since they make the violation more voluble.
∂20-Nov-85 1333 JAR@MIT-MC.ARPA Backquote algorithm
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 20 Nov 85 13:32:51 PST
Date: Wed, 20 Nov 85 16:34:57 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: Backquote algorithm
To: Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MIT-MC.ARPA
In-reply-to: Msg of 20 Nov 1985 0950-CST from David Bartley <Bartley%CSL60%ti-csl.csnet at CSNET-RELAY.ARPA>
Message-ID: <[MIT-MC.ARPA].725723.851120.JAR>
Date: 20 Nov 1985 0950-CST
From: David Bartley <Bartley%CSL60%ti-csl.csnet at CSNET-RELAY.ARPA>
I'd appreciate it if you'd send me a copy of your quasiquote expander.
Actually I think it'll be easier if I send it to everyone. I hope
people who don't care about this don't mind if I clutter their mailboxes
with it.
I won't guarantee that this 100% works, but I've tested it a little.
- Jonathan
;;; An expansion of `x or (#!quasiquote x) is obtained by calling
;;; the procedure EXPAND-QUASIQUOTE with argument x.
;;; The expansion involves only QUOTE forms and calls to LIST, APPEND,
;;; and CONS*. CONS* is the only nonstandard procedure, and its
;;; semantics could be given by
;;; (define (cons* x . rest)
;;; (if (null? rest) x (cons x (apply cons* rest))))
;;; It should be pretty easy to eliminate the use of CONS*, if that's
;;; desirable.
(define (expand-quasiquote x)
(define quasiquote-marker '#!quasiquote)
(define unquote-marker '#!unquote)
(define splice-marker '#!unquote-splice)
(define (finalize-quasiquote mode arg)
(cond ((eq? mode 'quote) `',arg)
((eq? mode 'unquote) arg)
((eq? mode 'splice)
(error ",@ in illegal context"
arg))
(else `(,mode ,@arg))))
;; The continuation argument c is passed two values, mode and arg.
;; These are interpreted as follows:
;; mode arg meaning
;; QUOTE x 'x
;; UNQUOTE x x
;; LIST (x1 x2 ...) (LIST x1 x2 ...)
;; CONS* (x1 x2 ...) (CONS* x1 x2 ...)
;; APPEND (x1 x2 ...) (APPEND x1 x2 ...)
(define (descend-quasiquote x level c)
(cond ((not (pair? x)) (c 'quote x))
((interesting-to-quasiquote? x quasiquote-marker)
(descend-quasiquote-pair x (1+ level) c))
((interesting-to-quasiquote? x unquote-marker)
(cond ((= level 0)
(c 'unquote (cadr x)))
(else
(descend-quasiquote-pair x (- level 1) c))))
((interesting-to-quasiquote? x splice-marker)
(cond ((= level 0)
(c 'splice (cadr x)))
(else
(descend-quasiquote-pair x (- level 1) c))))
(else
(descend-quasiquote-pair x level c))))
;; It would be simple to make this generate only a correct expansion;
;; most of the complexity here is in order to generate an
;; "optimized" expansion.
(define (descend-quasiquote-pair x level c)
(descend-quasiquote (car x) level
(lambda (car-mode car-arg)
(descend-quasiquote (cdr x) level
(lambda (cdr-mode cdr-arg)
(cond ((and (eq? car-mode 'quote) (eq? cdr-mode 'quote))
(c 'quote x))
((eq? car-mode 'splice)
(cond ((and (eq? cdr-mode 'quote) (null? cdr-arg))
(c 'unquote
car-arg))
((eq? cdr-mode 'append)
(c 'append
(cons car-arg cdr-arg)))
(else
(c 'append
(list car-arg
(finalize-quasiquote cdr-mode cdr-arg))))))
((and (eq? cdr-mode 'quote) (null? cdr-arg))
(c 'list
(list (finalize-quasiquote car-mode car-arg))))
((or (eq? cdr-mode 'list) (eq? cdr-mode 'cons*))
(c cdr-mode
(cons (finalize-quasiquote car-mode car-arg)
cdr-arg)))
(else
(c 'cons*
(list (finalize-quasiquote car-mode car-arg)
(finalize-quasiquote cdr-mode cdr-arg))))))))))
(define (interesting-to-quasiquote? x marker)
(and (pair? x)
(eq? (car x) marker)
(pair? (cdr x))
(null? (cddr x))))
(descend-quasiquote x 0 finalize-quasiquote))
∂20-Nov-85 1743 @MIT-MC.ARPA:BARTLEY%ti-csl.csnet@CSNET-RELAY.ARPA Multiple LAMBDA evaluations
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 20 Nov 85 17:42:43 PST
Received: from CSNET-RELAY.ARPA by MIT-MC.ARPA 20 Nov 85 20:44:39 EST
Received: from ti-csl by csnet-relay.csnet id ae16553; 20 Nov 85 20:13 EST
Date: 20 Nov 1985 1825-CST
From: David Bartley <Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Multiple LAMBDA evaluations
To: RRRS-Authors@mit-mc.arpa
cc: Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA
Received: from csl60 by ti-csl; Wed, 20 Nov 85 18:38 CST
I have two questions:
(1) Are issues like the following best raised in the general Scheme
community (e.g., SCHEME@MIT-MC) or here among the RRRS authors?
I'm a little confused about the intended difference when it comes to
language issues.
(2) When a given lambda expression is evaluated more than once, is it
required/allowed/disallowed that the procedure objects returned be
EQ? to each other?
The Common Lisp book addresses this issue on page 88: ``In
situations where a closure of a lambda-expression over the same
set of bindings may be produced more than once, the various
resulting closures may or may not be EQ, at the discretion of the
implementation.'' This allows certain useful optimizations and
clarifies the semantics of the language a bit.
My reading of the RRRS is that this interpretation is implicitly
supported for Scheme; however, there may be other opinions. Does
anyone object to adding similar language to the RRRS to clarify
our intent?
Regards,
David Bartley
-------
∂20-Nov-85 2352 @MIT-MC.ARPA:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA trace
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 20 Nov 85 23:46:53 PST
Received: from CSNET-RELAY.ARPA by MIT-MC.ARPA 21 Nov 85 02:48:32 EST
Received: from tektronix by csnet-relay.csnet id ac18731; 21 Nov 85 2:38 EST
From: Will Clinger <willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA>
To: scheme@mit-mc.ARPA
Received: from tekchips by tektronix with smtp ; 20 Nov 85 17:05:17 PST
Date: Wednesday, 20 Nov 85 16:52:06 PST
Subject: trace
A long time ago Jonathan asked what people did to trace self-recursive calls
to FACT when FACT is defined using the (DEFINE (FACT ...) ...) syntax. It
seems to me there are three obvious implementations of the trace facility,
with three distinct semantics:
1. Trace the variable. That is, (TRACE FACT) is a special form that turns
into something like (SET! FACT (MAKE-TRACED FACT)). This is how most
implementations seem to do it, though in some of them (e.g. MacScheme) TRACE
is a procedure and you have to say (TRACE 'FACT).
The disadvantage is that the self-recursive calls are not traced.
2. Trace the closure. That is, TRACE is a procedure and (TRACE FACT)
clobbers some field(s) of the data structure used to represent the procedure
stored in the variable FACT.
This will trace the self-recursive calls. The disadvantage is that it also
will trace calls to FOO where FOO is any variable that happens to hold the
same closure as is stored in the variable FACT.
3. Trace the code. That is, TRACE is a procedure and (TRACE FACT)
clobbers the first instruction(s) of the code portion of the closure.
This will trace the self-recursive calls. The disadvantage is that it also
will trace calls to any procedure obtained by closing the same lambda
expression. In fact, the precise semantics of this option is likely to
depend upon small details of an optimizing compiler.
It seems to me that implementations 1 and 2 are the most reasonable. Perhaps
users should be able to choose between the two.
Thanks to Norman Adams for his criticisms of the three implementations.
Peace, Will Clinger
∂21-Nov-85 0745 @MIT-MC.ARPA:JINX@MIT-OZ trace
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Nov 85 07:45:43 PST
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 21 NOV 85 10:39:58 EST
Date: 21 Nov 1985 10:36 EST (Thu)
Message-ID: <JINX.12161030631.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Will Clinger <willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA>
Cc: scheme@MIT-MC.ARPA
Subject: trace
In-reply-to: Msg of 20 Nov 1985 19:52-EST from Will Clinger <willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA>
Some comments about your TRACE implementation classification:
I do not think that the disadvantage you point out for option 2 is
undesirable. TRACE cleary implies a side effect since the behaviour
of some procedure changes. The point you make is no worse than the
fact that if A and B have the same (eq?) pair as their value, the
effect of SET-CAR! on one will be observed on the other also. Note
also that an optimizing compiler may decide to invoke FACT on
self-recursive calls bypassing the closure (by directly branching to
the entry point, for example), so this implementation is not
guaranteed to work on self-recursive calls either.
3 is not unreasonable either. There are situations in which this is
the desired behaviour. Consider the case of a procedure that returns
procedures, so there may be many instances of these procedures around.
This is common in message passing situations. It is occasionally
useful to be able to observe the invocations of all these procedures,
rather than the particular one we have a handle on. A TRACE option
which modifies the code would accomplish this task under most
circumstances.
In the presence of "hairy" enough compilers all implementations lose.
A compiler may decide, for example, to have 27 entry points to a given
procedure, each used by something else, and the TRACE facility would
have to know a fair amount about the actual code generated to be able
to "trap" all possible paths. Even worse if it decides to open code
the procedure in some places. The only possible solution in the worst
case is modifying the source code, recompiling and re-generating the
running environment, but even this may not work if the runtime
behaviour depended on events which cannot be duplicated.
MIT-Scheme has switched back and fourth between implementations 2 and
3. As far as I know it has never used implementation 1. I like
implementation 2 better, but there are occasions when 3 is desirable,
and the current implementation is implementation 3. It is also more
likely (though not without problems) that we can make this work even
in the case of compiled code.
∂21-Nov-85 0903 JAR@MIT-MC.ARPA description of MacScheme
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Nov 85 09:02:52 PST
Date: Thu, 21 Nov 85 12:04:39 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: description of MacScheme
To: SCHEME@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].726747.851121.JAR>
Date: Wednesday, 20 Nov 85 15:31:49 PST
From: Will Clinger <willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA>
To: Scheme-Request at mit-mc.ARPA
Re: description of MacScheme
Implementation: MacScheme
Implemented by: Will Clinger, Liz Heller, and John Ulrich
Supported by: Semantic Microsystems
Hardware: Apple Macintosh or Lisa (Mac XL).
Requires 512K RAM, can use up to 16M.
Operating Systems: Finder (Macintosh); MacWorks (Lisa).
Price/Availability: $125. Available since August 1985.
Implementation: Compiles to interpreted byte code.
Intended Use: Education, personal computing, AI applications
Contact: Semantic Microsystems
4470 S.W. Hall St., Suite 340
Beaverton, OR 97005
(503) 643-4539
MacScheme supports all essential and many optional features of the Revised
Revised Report on Scheme. It includes a compatibility package for use
with the Abelson and Sussman text, but environments are not supported.
The compiler and byte code architecture were described in Clinger's paper
at the 1984 Lisp conference. Numbers are implemented as a union of 30-bit
fixnums, bignums, and 32-bit flonums; bignum arithmetic is slow. The
system includes facilities for breaking, tracing, and debugging; most
run-time errors can be repaired in the debugger. There is a pretty printer.
An escape to machine code is documented for direct access to the Macintosh
Toolbox.
The system includes a simple editor that understands Scheme syntax and
makes good use of multiple windows and the mouse. This editor runs as a
foreground process while Scheme runs in the background.
MacScheme's speed is comparable to that of similar interpreters (MIT Scheme
on the HP 9836, TI Scheme) when hardware is taken into account. Non-tail-
recursive procedure calls are relatively slow in MacScheme but tight tail-
recursive loops are relatively fast. Interpreted MacScheme seems to run
about half as fast as compiled ExperLisp on the Macintosh.
∂21-Nov-85 0920 JAR@MIT-MC.ARPA Multiple LAMBDA evaluations
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Nov 85 09:20:35 PST
Date: Thu, 21 Nov 85 12:22:56 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: Multiple LAMBDA evaluations
To: Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MIT-MC.ARPA
In-reply-to: Msg of 20 Nov 1985 1825-CST from David Bartley <Bartley%CSL60%ti-csl.csnet at CSNET-RELAY.ARPA>
Message-ID: <[MIT-MC.ARPA].726762.851121.JAR>
Date: 20 Nov 1985 1825-CST
From: David Bartley <Bartley%CSL60%ti-csl.csnet at CSNET-RELAY.ARPA>
(1) Are issues like the following best raised in the general Scheme
community (e.g., SCHEME@MIT-MC) or here among the RRRS authors?
I'm a little confused about the intended difference when it comes to
language issues.
I figure that sending specific, technical implementation and language
design questions only to RRRS-Authors is appropriate since generally
most of us don't have the time to educate the 150 SCHEME list members
about things which will probably confuse or mislead them, and which they
probably don't care much about anyhow. Messages to RRRS-Authors are
easier to compose since we can sassume more sophistication on the part
of the recipients. Also, the smaller group can come to consensus on
complicated questions much faster and much less painfully than the
larger group. I don't mean this to sound elitist, only pragmatic.
(2) When a given lambda expression is evaluated more than once, is it
required/allowed/disallowed that the procedure objects returned
be EQ? to each other? ... Does anyone object to adding similar
language to the RRRS to clarify our intent?
This is a good idea; the wording in the CL manual is pretty good.
We definitely want to permit, but not require, things like
(LET ((Z ...))
(LET ((F (LAMBDA () (LAMBDA () Z))))
(EQ? (F) (F))))
and
(EQ? (LAMBDA (X) X) (LAMBDA (Y) Y))
and even
(LET ((F (LAMBDA (X) (LAMBDA () X))))
(EQ? (F 'A) (F 'A)))
to return true. The usual rule is that if there's any way to
distinguish two objects, EQ? of them must return false, but if there
ISN'T, EQ? is permitted to return true, and in certain special cases
(like that of symbols) is required to return true. This applies to
closures just as it does to numbers.
Maybe a 2nd edition of the RRRS is in order, say, for next summer? I'll
even volunteer to oversee its production, if no one else steps forward,
since the number of changes should be pretty small.
∂21-Nov-85 1306 @MIT-MC.ARPA:dyb%indiana.csnet@CSNET-RELAY.ARPA re: backquote
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Nov 85 13:04:03 PST
Received: from CSNET-RELAY.ARPA by MIT-MC.ARPA 21 Nov 85 16:06:05 EST
Received: from indiana by csnet-relay.csnet id ae24742; 21 Nov 85 15:25 EST
Date: Wed, 20 Nov 85 18:32:57 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: rrrs-authors@mit-mc.arpa
Subject: re: backquote
One potential functionality change, at least to Chez Scheme,
is that backquote errors are found at compilation time rather
than at read time. This is because it will not be possible
(all right, reasonable) for the reader to catch backquoteless
commas if the (quasiquote ...) syntax is allowable as a
replacement for backquote.
In any case, this strikes me as a feature, not a bug, since
the compiler can generally produce more informatitve error
messages than the reader.
Not only that, but we might find some meaning for (unquote x)
not inside a quasiquote. How about (eval x)?
Kent
∂21-Nov-85 1324 JAR@MIT-MC.ARPA trace
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Nov 85 13:22:35 PST
Date: Thu, 21 Nov 85 11:44:01 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: trace
To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
cc: SCHEME@MIT-MC.ARPA
In-reply-to: Msg of 20 Nov 85 16:52:06 PST from Will Clinger <willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA>
Message-ID: <[MIT-MC.ARPA].726726.851121.JAR>
Date: Wednesday, 20 Nov 85 16:52:06 PST
From: Will Clinger <willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA>
A long time ago Jonathan asked what people did to trace
self-recursive calls to FACT when FACT is defined using the (DEFINE
(FACT ...) ...) syntax. It seems to me there are three obvious
implementations of the trace facility, with three distinct
semantics:
1. Trace the variable. That is, (TRACE FACT) is a special form
that turns into something like (SET! FACT (MAKE-TRACED FACT)). This
is how most implementations seem to do it, though in some of them
(e.g. MacScheme) TRACE is a procedure and you have to say (TRACE
'FACT).
The disadvantage is that the self-recursive calls are not traced.
...
Thanks for your exposition. I was too lazy to articulate all this when
I sent out my earlier message, but it's what I had in mind.
For alternative 1., note that the procedure MAKE-TRACED could, in
principle, "look inside" the code for the procedure and produce a new
procedure, with new code, whose self-calls were traced. This still does
not imply a side-effect on the traced procedure or on its code.
I think all three alternatives have their place, but that (1) is
probably the safest and most useful, and if MAKE-TRACED did as I
suggest, I think it would be adequate. The others are potentially
dangerous, especially when applied to "system" procedures like
WRITE-CHAR.
[Of course this is implementation-specific; I'm certainly not suggesting
that a standard debugging interface should exist.]
∂21-Nov-85 1324 @MIT-MC.ARPA:CPH@MIT-OZ trace
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Nov 85 13:22:26 PST
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 21 NOV 85 11:07:36 EST
Date: Thu, 21 Nov 1985 10:46 EST
Message-ID: <CPH.12161032526.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: Will Clinger <willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA>
Cc: scheme@MIT-MC.ARPA
Subject: trace
In-reply-to: Msg of 20 Nov 1985 19:52-EST from Will Clinger <willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA>
It seems to me that all three of the options are reasonable, and users
should be able to choose any of them.
∂21-Nov-85 1324 @MIT-MC.ARPA:JINX@MIT-OZ Multiple LAMBDA evaluations
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Nov 85 13:22:07 PST
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 21 NOV 85 10:50:22 EST
Date: 21 Nov 1985 10:45 EST (Thu)
Message-ID: <JINX.12161032360.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: David Bartley <Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA>
Cc: RRRS-Authors@MIT-MC.ARPA
Subject: Multiple LAMBDA evaluations
In-reply-to: Msg of 20 Nov 1985 19:25-EST from David Bartley <Bartley%CSL60%ti-csl.csnet at CSNET-RELAY.ARPA>
We should certainly not require that both evaluations return EQ?
objects.
Note: Is it true that the only way that a lambda expression can be
re-evaluated in the same environment is by using
call-with-current-continuation?
∂21-Nov-85 1805 @MIT-MC.ARPA:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA EQ? and procedures, numbers, etc
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Nov 85 18:04:47 PST
Received: from CSNET-RELAY.ARPA by MIT-MC.ARPA 21 Nov 85 20:52:49 EST
Received: from tektronix by csnet-relay.csnet id ao26285; 21 Nov 85 18:45 EST
From: Will Clinger <willc%tekchips@tektronix.CSNET>
To: RRRS-AUTHORS@mit-mc.ARPA
Received: from tekchips by tektronix with smtp ; 21 Nov 85 14:46:45 PST
Date: Thursday, 21 Nov 85 13:36:39 PST
Subject: EQ? and procedures, numbers, etc
RRRS says that (EQ? x x) is always true, but it would be better if the value
returned by EQ? were undefined when applied to procedure values and numbers.
The current wording of RRRS forces a formal semantics of Scheme to associate
locations with procedure values and numbers. These locations have no
purpose other than to make the semantics of EQ? work as in RRRS, and they
make the semantics much uglier.
The ugliness of the semantics results in more complex and less effective
optimizing compilers.
I thought that it would be a cleaner semantics if (EQ? x x) always returned
true, but I was wrong. It is actually a cleaner semantics if the value of
EQ? is unspecified when both its arguments are procedures and when both its
arguments are numbers. When strings are immutable (as in the essential
subset of Scheme) EQ? should be unspecified when both its arguments are
strings. Similarly EQ? should be unspecified when both its arguments are
characters (unless we want to insist that either (1) characters are
represented uniquely (e.g. immediates) or (2) EQ? does something
complicated).
Will Clinger
∂21-Nov-85 1926 @MIT-MC.ARPA:BARTLEY%ti-csl.csnet@CSNET-RELAY.ARPA Re: Multiple LAMBDA evaluations
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Nov 85 19:25:02 PST
Received: from CSNET-RELAY.ARPA by MIT-MC.ARPA 21 Nov 85 22:26:54 EST
Received: from ti-csl by csnet-relay.csnet id a028471; 21 Nov 85 22:17 EST
Date: 21 Nov 1985 1817-CST
From: David Bartley <Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Re: Multiple LAMBDA evaluations
To: JINX%MIT-OZ@mit-mc.arpa, Bartley%CSL60%ti-csl.csnet@csnet-relay.arpa
cc: RRRS-Authors@mit-mc.arpa, Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA
In-Reply-To: Your message of 21-Nov-85 1045-CST
Received: from csl60 by ti-csl; Thu, 21 Nov 85 19:14 CST
From JINX:
> We should certainly not require that both evaluations return EQ?
> objects.
I'm more concerned about whether I am ALLOWED to return values that
are EQ?, not that I might be REQUIRED to.
> Note: Is it true that the only way that a lambda expression can be
> re-evaluated in the same environment is by using
> call-with-current-continuation?
No. Consider the following...
(define foo
(lambda (msg)
(case msg
...
((XXX) (lambda (args) do-something))
...)))
Here, FOO returns a closure every time it is called with argument XXX.
I expect that most implementations would ``cons up'' a new closure
object every time. The following code does the same thing, but the
closures returned are always EQ? to each other.
(define foo
(let ((xxx-handler (lambda (args) do-something)))
(lambda (msg)
(case msg
...
((XXX) xxx-handler)
...))))
My motivation is to allow an optimizing compiler to map code like the
first into code like the second. This is related to the traditional
compiler optimization which moves invariant computations out of loops.
Here's another example:
(define bar
(lambda (x)
(map (lambda (y) (+ y 13))
x)))
I would like to transform this into...
(define bar
(let ((temp (lambda (y)(+ y 13))))
(lambda (x)
(map temp x))))
Regards,
David Bartley
-------
∂21-Nov-85 2015 @MIT-MC.ARPA:JINX@MIT-OZ Multiple LAMBDA evaluations
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 21 Nov 85 19:59:31 PST
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 21 NOV 85 23:01:44 EST
Date: 21 Nov 1985 22:58 EST (Thu)
Message-ID: <JINX.12161165719.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: David Bartley <Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA>
Cc: RRRS-Authors@MIT-MC.ARPA
Subject: Multiple LAMBDA evaluations
In-reply-to: Msg of 21 Nov 1985 19:17-EST from David Bartley <Bartley%CSL60%ti-csl.csnet at CSNET-RELAY.ARPA>
Your counter examples do not disprove my claim. In all cases no
lambda expression is evaluated twice in the same environment. The two
environments (as with JAR's example) may be isomorphic (same variables
and same values), but not identical. In the absence of incremental
definition, or if there is no handle to these environments, the
distinction is moot, but in the presence of these "features" they are
not the same. I guess that the difference is that I view environments
as objects (probably influneced because of our dialect), and
conceptually a new one is created every time a lambda expression is
applied, even if this lambda expression has no bindings.
I think that the only cases which force re-evaluation in the same environment
(the way I view them) are contorted examples like
(define fact
(let ((there&then '()))
(set! there&then
(call-with-current-continuation
(lambda (here&now) here&now)))
(let ((y-like (lambda (x) (there&then x)))) ;HERE
(y-like (lambda (f)
(lambda (n)
(if (= n 0)
1
(* n ((f f) (-1+ n))))))))))
Note that the 2 lambdas marked by HERE (the explicit one, and the
implicit one in the LET expression) are evaluated twice in the
environment created by the outermost LET.
∂22-Nov-85 1054 @MIT-MC.ARPA:BARTLEY%ti-csl.csnet@CSNET-RELAY.ARPA Re: Multiple LAMBDA evaluations
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Nov 85 10:25:51 PST
Received: from CSNET-RELAY.ARPA by MIT-MC.ARPA 22 Nov 85 13:12:13 EST
Received: from ti-csl by csnet-relay.csnet id ad04001; 22 Nov 85 12:55 EST
Date: 22 Nov 1985 0928-CST
From: David Bartley <Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Re: Multiple LAMBDA evaluations
To: JINX%MIT-OZ@mit-mc.arpa, Bartley%CSL60%ti-csl.csnet@csnet-relay.arpa
cc: RRRS-Authors@mit-mc.arpa, Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA
In-Reply-To: Your message of 21-Nov-85 1817-CST
Received: from csl60 by ti-csl; Fri, 22 Nov 85 10:34 CST
> Your counter examples do not disprove my claim. In all cases no
> lambda expression is evaluated twice in the same environment.
> [...] I guess that the difference is that I view environments as
> objects (probably influneced because of our dialect), and
> conceptually a new one is created every time a lambda expression
> is applied, even if this lambda expression has no bindings.
Sorry, I've tripped up on another assumption that needs to be
discussed! In my first example (reproduced below), I assumed that the
DO-SOMETHING in the body of the inner lambda was an expression that
did not reference MSG. Thus, in a pragmatic sense, it didn't have to
be closed over that part of the environment. This is the analysis
that permits a compiler to transform
(define foo
(lambda (msg)
(case msg
...
((XXX) (lambda (args) do-something))
...)))
into
(define foo
(let ((xxx-handler (lambda (args) do-something)))
(lambda (msg)
(case msg
...
((XXX) xxx-handler)
...))))
since I'm moving the lambda relative to its environment.
So, I agree with your point, but I'm shifting the question a bit: Is
there a consensus that these kinds of optimizations are permitted?
To my knowledge, the only way to know whether a procedure object has
closed over the entire ``visible'' environment or just the part of it
which it references is to have something like MIT Scheme's
PROCEDURE-ENVIRONMENT. This function returns the environment over
which a procedure was closed. Our implementation of Scheme supports
first-class environments in the MIT sense and has this function, but
we consider it a debugging tool only, and do not guarantee that it
returns the entire environment unless the compilation took place in
``debug mode.''
So, I consider the environment closed over to be an abstraction with
different implementations possible. Thus, if the environments may or
may not be EQ?, the closures may or may not be EQ?.
Regards,
David Bartley
-------
∂22-Nov-85 1135 @MIT-MC.ARPA:KMP@SCRC-STONY-BROOK.ARPA EQ? and procedures, numbers, etc
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Nov 85 11:35:14 PST
Received: from SCRC-STONY-BROOK.ARPA by MIT-MC.ARPA 22 Nov 85 14:02:00 EST
Received: from DUPAGE.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 360602; Fri 22-Nov-85 13:58:06-EST
Date: Fri, 22 Nov 85 13:59 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: EQ? and procedures, numbers, etc
To: willc%tekchips@tektronix.CSNET
cc: RRRS-AUTHORS@MIT-MC.ARPA
In-Reply-To: The message of 21 Nov 85 16:36-EST from Will Clinger <willc%tekchips@tektronix.CSNET>
Message-ID: <851122135902.0.KMP@DUPAGE.SCRC.Symbolics.COM>
Date: Thursday, 21 Nov 85 13:36:39 PST
From: Will Clinger <willc%tekchips@tektronix.CSNET>
RRRS says that (EQ? x x) is always true, but it would be better if the value
returned by EQ? were undefined when applied to procedure values and numbers.
I strongly disagree.
The current wording of RRRS forces a formal semantics of Scheme to associate
locations with procedure values and numbers. These locations have no
purpose other than to make the semantics of EQ? work as in RRRS, and they
make the semantics much uglier. The ugliness of the semantics results in
more complex and less effective optimizing compilers.
I have yet to see a convincing example of this claim. Note, however, that I consider
object identity to be one of the most indispensible things about symbolic processing
and would not be likely to be willing to give up the only function which predicates
such identity regardless of whether such an example could be constructed. However,
for now perhaps you could just enumerate some of the troublesome cases for me to respond
to more specifically.
I thought that it would be a cleaner semantics if (EQ? x x) always returned
true, but I was wrong. It is actually a cleaner semantics if the value of
EQ? is unspecified when both its arguments are procedures and when both its
arguments are numbers. When strings are immutable (as in the essential
subset of Scheme) EQ? should be unspecified when both its arguments are
strings. Similarly EQ? should be unspecified when both its arguments are
characters (unless we want to insist that either (1) characters are
represented uniquely (e.g. immediates) or (2) EQ? does something
complicated).
I bet it makes things easier to be able to ignore this distinction. I don't know
if programming ease and code size are always the same as cleanliness. They are
clearly related. It's possible that even O(size) is proportional to O(clean),
but I doubt that size is proportional to clean. Eg, consider:
(DEFINE SUCCESSOR (X) (+ X 1))
(DEFINE SUCCESSOR (X)
(UNLESS (NUMBERP X) (ERROR "Don't know the successor of ~S" X))
(+ X 1))
Certainly the first program is smaller. It is probably simpler to write.
It is not be simpler to use and may be harder to use. Whether it is cleaner
seems to me to be in a gray area.
I cite as precedent the case of CALL-WITH-CURRENT-CONTINUATION. Everyone seemed to
agree that it was easier to compile/optimize code which doesn't allow returning
these upward. The argument for pushing it through was not that it made the
implementation simpler, since in fact it complicated it. It was instead the fact
that it was (a) at least possible to implement and (b) much simpler to some write
programs when this feature was available. It seems to me that the situation is
similar for EQ? -- I do not want to give up this feature. You (the compiler writer)
have to solve this problem only once. I (the programmer) will have to solve it
repeatedly if you do not solve it once for me.
∂22-Nov-85 1515 @MIT-MC.ARPA:gls@THINK-AQUINAS.ARPA EQ? and procedures, numbers, etc
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Nov 85 14:43:56 PST
Received: from THINK-AQUINAS.ARPA by MIT-MC.ARPA 22 Nov 85 17:00:06 EST
Received: from THINK-YON.ARPA by THINK-AQUINAS.ARPA via CHAOS with CHAOS-MAIL id 2185; Fri 22-Nov-85 16:59:24-EST
Date: Fri, 22 Nov 85 16:58 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: EQ? and procedures, numbers, etc
To: KMP@SCRC-STONY-BROOK.ARPA, willc%tekchips%tektronix@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MIT-MC.ARPA, gls@THINK-AQUINAS.ARPA
In-Reply-To: <851122135902.0.KMP@DUPAGE.SCRC.Symbolics.COM>
Message-ID: <851122165853.8.GLS@THINK-YON.ARPA>
KMP is right in identifying the question of object identity
as a key issue. But there are two separate issues here:
(1) Are two evaluations, of the same LAMBDA-expression, that are
distinct in time permitted to produce objects that are not distinct as
determined by "EQ?"? In simpler terms, may two things that you might
expect to be different turn out to be the same? (Call this property
"coalescence".)
(2) Once a single object has been produced and named, is the
implementation allowed to duplicate it at will in such a way as to cause
two distinct references to its name to result in values that are
distinct to "EQ?"? In simpler terms, may one thing turn out to be two
different things? (Call this property "splitting".)
Now Common Lisp permits splitting for characters and numbers with
respect to "EQ" (but not with respect to "EQL"). It permits coalescing
for numbers, characters, and closures of lambda expressions.
I feel that splitting is a semantically bad thing to have in a LISP-like
language, because I think name-reference should be free of side effects!
It was introduced into Common Lisp only for the sake of certain
implementational efficiencies. If one removes EQ from the language and
leaves only EQL, then there is no splitting. I would have preferred for
EQ to have the current semantics of EQL, but it was too ingrained into
everyone's mind (including mine) that EQ means "compare the pointers",
which is an implementation notion rather than a language notion.
On the other hand, I feel that coalescing is a perfectly legitimate
optimization. If two objects cannot be distinguished, then it should be
legitimate to merge them. If there are no RPLACA or RPLACD operations
on CONS cells, then hash-consing is a legitimate optimization (and,
indeed, perhaps EQ should be required to behave as EQUAL on CONS cells
in the absence of such side effects!). It is important to have some
means of generating distinct objects, but it is not clear that
lambda-expressions need to be that means.
It is not always legitimate to coalesce two closures, but frequently a
static analysis can determine that no distinguishing side effects are
possible and that therefore two closures would be operationally
identical.
In short, my feelings are: splitting, no: (EQ? X X) should always be true;
coalescing, maybe: it can be a legitimate optimization.
--Guy
∂22-Nov-85 1628 @MIT-MC.ARPA:adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: trace
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Nov 85 16:23:06 PST
Received: from CSNET-RELAY.ARPA by MIT-MC.ARPA 22 Nov 85 19:24:05 EST
Received: from tektronix by csnet-relay.csnet id ai07029; 22 Nov 85 18:41 EST
From: Norman Adams <adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA>
To: tektronix!jinx%mit-oz@mit-mc.ARPA
Cc: willc%tektronix.csnet@CSNET-RELAY.ARPA, scheme@mit-mc.ARPA
Fcc: Out
Received: from tekchips by tektronix with smtp ; 22 Nov 85 12:45:49 PST
Date: Friday, 22 Nov 85 12:32:13 PST
Subject: Re: trace
In-reply-to: Your message of 21 Nov 1985 10:36 EST (Thu)., <JINX.12161030631.BABYL@MIT-OZ>
TRACE cleary implies a side effect since the behaviour
of some procedure changes.
This is not obvious to me. TRACE reports on an activity in the
system. The action of the traced procedure is unchanged. Just to
be extreme, TRACE might be implemented with external hardware,
something like a really smart logic analyzer.
I think we can understand the meaning of the phrases "trace the
variable," "trace the closure," and "trace the code" independent of the
particular implementations. Is there some concurrence about what an
unsophisticated user expects when he or she writes (TRACE FOO)? I think
it is undesirable that the effect depends on the form of the DEFINE. I
also think it is confusing to have indirect recursions appear in the
TRACE output, when the self recursions are ommitted.
I guess this is a result of (define (v0 v1...) ...) being subtley
different than (define v0 (lambda (v1 ...) ...)) in the treatment of
v0. I don't see any advantage to having this difference, aside from
possible runtime efficiency.
In the presence of "hairy" enough compilers all implementations lose.
Given that we know the desired effect of TRACE in terms of the language,
the implementor of an optimizing compiler can choose to support TRACE or
provide some coherent preemption of it. In the presence of an
optimizing compiler, I don't see how to make trace independent of the
compiler without preemting either the compiler or the TRACE facility.
-Norman Adams
∂22-Nov-85 2038 @MIT-MC.ARPA:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: backquote proposal
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Nov 85 20:38:01 PST
Received: from CSNET-RELAY.ARPA by MIT-MC.ARPA 22 Nov 85 23:40:19 EST
Received: from indiana by csnet-relay.csnet id a009014; 22 Nov 85 23:28 EST
Date: Fri, 22 Nov 85 15:32:26 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: Bartley%csl60%ti-csl.csnet@CSNET-RELAY.ARPA
Subject: Re: backquote proposal
Cc: rrrs-authors@mit-mc.arpa
Chez Scheme performs the optimization you refer to, in the case
where no free variables are referenced in the lambda expression.
I see nothing wrong with it, since closing is not an explicit
allocation operation in the same sense as cons or make-vector.
Kent
∂22-Nov-85 2101 @MIT-MC.ARPA:JINX@MIT-OZ Multiple LAMBDA evaluations
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Nov 85 21:01:26 PST
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 23 NOV 85 00:03:20 EST
Date: 23 Nov 1985 00:01 EST (Sat)
Message-ID: <JINX.12161439266.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: David Bartley <Bartley%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA>
Cc: RRRS-Authors@MIT-MC.ARPA
Subject: Multiple LAMBDA evaluations
In-reply-to: Msg of 22 Nov 1985 10:28-EST from David Bartley <Bartley%CSL60%ti-csl.csnet at CSNET-RELAY.ARPA>
I guess the main difference is how the system is viewed. We view the
system as an interpreted system primarily, and compilation is
something we put up with only for the sake of efficiency on the kinds
of machines we unfortunately have to work with. Ideally compilation
preserves the behaviour even as far as things like TRACE or
PROCEDURE-ENVIRONMENT are concerned, thus those optimizations would
not be allowed in the absence of declarations. In practice, given the
limitations of the hardware we deal with, we allow some of these
conceptual declarations to be implicit in the compiler (otherwise
there would be no use to compiling in the first place). Thus we
tolerate potential incompatibilities between compiled and interpreted
code because of efficiency constraints. We view compilation as
something that happens only after the code has being debugged
significantly, so the above procedures are unlikely to be used at this
stage.
∂22-Nov-85 2157 @MIT-MC.ARPA:JINX@MIT-OZ trace
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 22 Nov 85 21:57:42 PST
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 23 NOV 85 00:59:34 EST
Date: 23 Nov 1985 00:32 EST (Sat)
Message-ID: <JINX.12161444926.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: tekchips!adams%tektronix.csnet@CSNET-RELAY.ARPA
Cc: scheme@MIT-MC.ARPA, tektronix!jinx%MIT-OZ@MIT-MC.ARPA,
willc%tektronix.csnet@CSNET-RELAY.ARPA
Subject: trace
In-reply-to: Msg of 22 Nov 1985 15:32-EST from tekchips!adams%tektronix.csnet at CSNET-RELAY.ARPA
TRACE cleary implies a side effect since the behaviour
of some procedure changes.
This is not obvious to me. TRACE reports on an activity in the
system. The action of the traced procedure is unchanged. Just to
be extreme, TRACE might be implemented with external hardware,
something like a really smart logic analyzer.
The values returned by the traced procedure are the same (hopefully),
but there is certainly a change in behaviour in the procedure. It
prints (writes?) some stuff which it was not printing before, so its
behaviour has changed, irrelevant of whether you implement the TRACE
facility by modifying the procedure (closure, code, or variable), or
APPLY.
What you say is similar to saying that SET-CAR! does not really change
the appropriate pair, but rather changes the CAR procedure so that if
it sees that its argument is the "modified" pair, it gives the new
"car" as its answer, as opposed to the "real" car. Sorry, but I think
you are just playing word games.
.. is undesirable that the effect depends on the form of the DEFINE. I
also think it is confusing to have indirect recursions appear in the
TRACE output, when the self recursions are ommitted.
What do you mean by indirect recursions? I think you are too harsh on
DEFINE. It seems from your message that you would be upset if in the
following
(define (fact n)
(if (= n 0)
1
(* n (fact (-1+ n)))))
self recursive calls were not displayed, but you would be perfectly willing
to tolerate that behaviour in
(define fact
(letrec ((fact (lambda (n)
(if (= n 0)
1
(* n (fact (-1+ n)))))))
fact))
. I see no difference. As far as I'm concerned, I would like to see
all instances where the object which FOO is bound to (eq? problems
again) is (conceptually) invoked. This obviously presupposes a
particular model of evaluation, but that is probably true of each
user.
I don't think that we will be able to agree on what the "right"
behaviour is since the "right" behaviour depends on the situation, and
there are probably cases which we have not included in our
classification where any of them will not do exactly what we want.
∂25-Nov-85 1133 @MIT-MC.ARPA:KMP@SCRC-STONY-BROOK.ARPA EQ? and procedures, numbers, etc
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 25 Nov 85 11:33:19 PST
Received: from SCRC-STONY-BROOK.ARPA by MIT-MC.ARPA 25 Nov 85 14:31:44 EST
Received: from DUPAGE.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 362279; Mon 25-Nov-85 14:22:54-EST
Date: Mon, 25 Nov 85 14:24 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: EQ? and procedures, numbers, etc
To: gls@THINK-AQUINAS.ARPA
cc: KMP@SCRC-STONY-BROOK.ARPA, willc%tekchips%tektronix@CSNET-RELAY.ARPA,
RRRS-AUTHORS@MIT-MC.ARPA
In-Reply-To: <851122165853.8.GLS@THINK-YON.ARPA>
Message-ID: <851125142400.0.KMP@DUPAGE.SCRC.Symbolics.COM>
Hmm, let me pose a few concrete examples to test that you and I agree.
You called this splitting:
[1] (LET ((X C) (Y C))
(EQ? X Y))
You and I seem to agree that evaluating this expression should always
yield true. Further, I suggest that the following are also in the same
category and assume that we both agree that these should -always- return
true as well:
[1a] (LET ((F (LAMBDA () C)))
(EQ? (F) (F)))
[1b] (LET ((F (LAMBDA () '(ANY EXPRESSION))))
(EQ? (F) (F)))
You called this coalescing:
[2] (LET ((F (LAMBDA () (LAMBDA () 3))))
(EQ? (F) (F)))
I agree with you that it is reasonable for either of {true,false} to be
returned from evaluating this. I suggest that the following are special
cases of the same situation, and that it may not be possible to predict
which of {true,false} will be returned:
[2a] (LET ((X '(ANY EXPRESSION))
(Y '(ANY EXPRESSION)))
(EQ? X Y))
[2b] (LET ((F (LAMBDA () '(ANY EXPRESSION)))
(G (LAMBDA () '(ANY EXPRESSION))))
(EQ? (F) (G)))
Among other things, 2b is important because of code constructed by
expressions like:
`(LET ((F (LAMBDA () ',EXP))
(G (LAMBDA () ',EXP)))
(EQ? (F) (G)))
We would like to constrain the semantics of the resulting expression to not
be perturbed by first writing the expression to an intermediate file and
then re-reading it.
Put another way -- with the exception of objects like symbols (which are
intentionally interned), sharing of memory should not affect the semantics
of an expression (though it may affect its perceived behavior). On the
other hand, certain identifiable patterns of data flow should be defined
to preserve sharing in a well-defined way, in order to ease certain
programming tasks and also (for not reasons that are not unrelated) to
allow various theorems, transformations, proofs, and optimizations to be
conveniently written about those patterns.
∂25-Nov-85 1426 @MIT-MC.ARPA:JINX@MIT-OZ EQ? and procedures, numbers, etc
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 25 Nov 85 14:25:57 PST
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 25 NOV 85 17:20:22 EST
Date: 25 Nov 1985 17:17 EST (Mon)
Message-ID: <JINX.12162152284.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Cc: gls@AQUINAS.THINK.COM, RRRS-AUTHORS@MIT-MC.ARPA,
willc%tekchips%tektronix@CSNET-RELAY.ARPA
Subject: EQ? and procedures, numbers, etc
In-reply-to: Msg of 25 Nov 1985 14:24-EST from Kent M Pitman <KMP at SCRC-STONY-BROOK.ARPA>
I don't know if GLS agrees with you, but I certainly do.
∂25-Nov-85 1551 @MIT-MC.ARPA:adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA trace, language vs. implementation
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 25 Nov 85 15:48:32 PST
Received: from CSNET-RELAY.ARPA by MIT-MC.ARPA 25 Nov 85 18:50:13 EST
Received: from tektronix by csnet-relay.csnet id ae04345; 25 Nov 85 18:39 EST
From: Norman Adams <adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA>
To: tektronix!jinx%mit-oz@mit-mc.ARPA
Cc: scheme@mit-mc.ARPA
Fcc: Out
Received: from tekchips by tektronix with smtp ; 25 Nov 85 11:15:24 PST
Date: Monday, 25 Nov 85 11:06:35 PST
Subject: trace, language vs. implementation
In-reply-to: Your message of 23 Nov 1985 00:32 EST (Sat)., <JINX.12161444926.BABYL@MIT-OZ>
>>> TRACE cleary implies a side effect since the behaviour
>>> of some procedure changes.
>>
>> This is not obvious to me. TRACE reports on an activity in the
>> system. The action of the traced procedure is unchanged. Just to
>> be extreme, TRACE might be implemented with external hardware,
>> something like a really smart logic analyzer.
>
> The values returned by the traced procedure are the same (hopefully),
> but there is certainly a change in behaviour in the procedure. It
> prints (writes?) some stuff which it was not printing before, so its
> behaviour has changed, irrelevant of whether you implement the TRACE
> facility by modifying the procedure (closure, code, or variable), or
> APPLY.
There is no requirement that the procedure print the message. My
analogy to a logic analyzer still holds. Something external to the
procedure could be report on the activity of the procedure.
You seem to be unwilling to consider the behavior of TRACE separate
from its implementation.
> What you say is similar to saying that SET-CAR! does not really change
> the appropriate pair, but rather changes the CAR procedure so that if
> it sees that its argument is the "modified" pair, it gives the new
> "car" as its answer, as opposed to the "real" car. Sorry, but I think
> you are just playing word games.
I find this comparison unconvincing. First, SET-CAR! is a construct of
the language; TRACE is a command to the programming environment. My
guess would be that you do not make this distinction; though, I think it
would be a mistake not to. Second, SET-CAR! is defined to have a side
effect, TRACE can be specified without resorting to side effects:
"After issuing (TRACE <proc>) the procedure trace facility with report
calls to and returns from <proc>." I note that you wrote "TRACE", not
"TRACE!". I think there is more to what I am saying than word games.
Your example demonstrates that the semantics of "side-effect" can be
implemented without apparent side effect; the reverse is also possible
(you can implement FP in C).
-Norman
∂25-Nov-85 1802 @MIT-MC.ARPA:adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: trace
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 25 Nov 85 17:27:21 PST
Received: from CSNET-RELAY.ARPA by MIT-MC.ARPA 25 Nov 85 18:50:25 EST
Received: from tektronix by csnet-relay.csnet id ag04345; 25 Nov 85 18:40 EST
From: Norman Adams <adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA>
To: tektronix!jinx%mit-oz@mit-mc.ARPA
Cc: scheme@mit-mc.ARPA
Fcc: Out
Received: from tekchips by tektronix with smtp ; 25 Nov 85 12:25:15 PST
Date: Monday, 25 Nov 85 12:09:52 PST
Subject: Re: trace
In-reply-to: Your message of 23 Nov 1985 00:32 EST (Sat)., <JINX.12161444926.BABYL@MIT-OZ>
> > .. is undesirable that the effect depends on the form of the DEFINE. I
> > also think it is confusing to have indirect recursions appear in the
> > TRACE output, when the self recursions are ommitted.
>
> What do you mean by indirect recursions? I think you are too harsh on
> DEFINE. It seems from your message that you would be upset if in the
> following
>
> (define (fact n)
> (if (= n 0)
> 1
> (* n (fact (-1+ n)))))
>
> self recursive calls were not displayed, but you would be perfectly willing
> to tolerate that behaviour in
>
> (define fact
> (letrec ((fact (lambda (n)
> (if (= n 0)
> 1
> (* n (fact (-1+ n)))))))
> fact))
>
> . I see no difference.
There may be no good answer. My point was that if I write
(define (foo x)
... (foo x) ...
... (bar x) ... )
(define (bar x)
... (foo x) ...
... (bar x) ... )
that I am going to see calls from FOO to BAR, and from BAR to FOO,
but not from FOO to FOO, or from BAR to BAR. I find this property of
this variant of DEFINE strange. At least is this version:
> (define fact
> (letrec ((fact (lambda (n)
> (if (= n 0)
> 1
> (* n (fact (-1+ n)))))))
> fact))
>
there are two different variables named FACT apparent in the code the
user wrote.
> As far as I'm concerned, I would like to see
> all instances where the object which FOO is bound to (eq? problems
> again) is (conceptually) invoked. This obviously presupposes a
> particular model of evaluation, but that is probably true of each
> user.
Great! Here are some possible trace facilities (specified in terms
of the language):
(1) Trace all calls to the procedure which is the value of a given
variable (what you said). "trace the closure"
(2) Trace all evaluations of a particular combination (specify
a call in a particular piece of source). "trace the source"
(3) Trace all evaluations of all combinations where the procedure in the
combination was obtained by evaluating a given variable.
"trace the variable"
(4) Trace all evaluations of all combinations where the procedure is
a value that resulted from the evaluation of a given lambda-expression.
(You choose how to specify the lambda). "trace the code"
Given that we decided that some or all of these were useful, we might
discuss the relative difficulty of implementing them; or perhaps,
how these might or might not be supported in the presence of an
optimizing compiler. This was the point of my first message.
I do not think that TRACE merrits all this discussion. I do think
there is an important issue at hand: how to implement a language that
is both efficient and easy to debug. Perhaps a change in the focus
of this discussion would show up some interesting differences in
Scheme implementation philosophies.
-Norman
∂25-Nov-85 1812 @MIT-MC.ARPA:JINX@MIT-OZ trace, language vs. implementation
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 25 Nov 85 18:00:54 PST
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 25 NOV 85 20:57:36 EST
Date: 25 Nov 1985 20:42 EST (Mon)
Message-ID: <JINX.12162189507.BABYL@MIT-OZ>
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
To: tekchips!adams%tektronix.csnet@CSNET-RELAY.ARPA
Cc: scheme@MIT-MC.ARPA, tektronix!jinx%MIT-OZ@MIT-MC.ARPA
Subject: trace, language vs. implementation
In-reply-to: Msg of 25 Nov 1985 14:06-EST from tekchips!adams%tektronix.csnet at CSNET-RELAY.ARPA
When I said
>>>> TRACE cleary implies a side effect since the behaviour
>>>> of some procedure changes.
I did not mean to imply that the side effect was done on the procedure
(variable, etc.) but that a side effect was done somewhere. In
particular, APPLY can be changed to take care of TRACE.
>There is no requirement that the procedure print the message. My
>analogy to a logic analyzer still holds. Something external to the
>procedure could be report on the activity of the procedure.
You've moved the side effect one level out. Conceptually SOMETHING,
SOMEWHERE, is taking some action which it would not have taken before.
I do not know what you call this if it is not a side effect.
1>You seem to be unwilling to consider the behavior of TRACE separate
1>from its implementation.
>> What you say is similar to saying that SET-CAR! does not really change
>> the appropriate pair, but rather changes the CAR procedure so that if
>> it sees that its argument is the "modified" pair, it gives the new
>> "car" as its answer, as opposed to the "real" car. Sorry, but I think
>> you are just playing word games.
2>I find this comparison unconvincing. First, SET-CAR! is a construct of
2>the language; TRACE is a command to the programming environment. My
2>guess would be that you do not make this distinction; though, I think it
2>would be a mistake not to. Second, SET-CAR! is defined to have a side
2>effect, TRACE can be specified without resorting to side effects:
2>"After issuing (TRACE <proc>) the procedure trace facility with report
2>calls to and returns from <proc>." I note that you wrote "TRACE", not
2>"TRACE!". I think there is more to what I am saying than word games.
Please be consistent. Either TRACE is a part of the language (vs. "the
programming environment") or it isn't. If it is part of the
programming environment we should not worry about semantics since no
portable code will (hopefully) depend on its behaviour. Its
implementation is the only interesting part. If it is part of the
language my analogy holds and we lose anyway since it involves a
side effect (which was my original point).
I agree with JAR in that we should not attempt to agree on debugging
tools, since debugging is a highly personal activity, and we would be
asking people to support models which do not necessarily agree with
their own. In other words, TRACE is part of the programming system
and we should not constrain it in any way in the same way that we do
not ask people to use a particular editor. There is too much personal
taste involved.
∂26-Nov-85 0049 @MIT-MC.ARPA:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA EQ? and procedures etc
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 26 Nov 85 00:48:51 PST
Received: from CSNET-RELAY.ARPA by MIT-MC.ARPA 26 Nov 85 03:51:04 EST
Received: from tektronix by csnet-relay.csnet id aa07476; 26 Nov 85 3:38 EST
From: Will Clinger <willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA>
To: RRRS-AUTHORS@mit-mc.ARPA
Received: from tekchips by tektronix with smtp ; 25 Nov 85 16:35:13 PST
Date: Monday, 25 Nov 85 16:29:22 PST
Subject: EQ? and procedures etc
Ok, it's pretty clear that people want (EQ? X X) to be true. I bow to the
majority, but I want to discuss some of the points that have been raised.
This is a long message.
----------------------------------------------------------------
Will:
The current wording of RRRS forces a formal semantics of Scheme to associate
locations with procedure values and numbers. These locations have no
purpose other than to make the semantics of EQ? work as in RRRS, and they
make the semantics much uglier. The ugliness of the semantics results in
more complex and less effective optimizing compilers.
Kent:
I have yet to see a convincing example of this claim.... However, for now
perhaps you could just enumerate some of the troublesome cases for me to
respond to more specifically.
Will:
I made about four claims in the paragraph Kent cites, all of which are
debatable, and I'm not sure which one(s) he doesn't believe so I will run
through all of them. First of all, neither the Muchnik-Pleban semantics nor
the semantics I wrote for my 1984 Lisp conference paper can handle the
semantics of EQ? as in RRRS. The problem is that the domain equation for
expressed values is something like
E = {#!true, #!false, #!null} +
F + ; procedure values
R + ; numbers
Q + ; symbols
LxL + ; pairs
L* + ; vectors
L* ; strings
where L is the domain of locations and + is a disjoint union. The equation
for procedure values is F = E* --> K --> C, so the EQ? procedure sees a
procedure as a higher order (mathematical) function, not as a pointer to a
data structure encoding the higher order function. The obvious fix is to
change the equation for procedure values to be F = L x (E* --> K --> C).
This fix is necessary in order that an implementation be *allowed* to say
for example that (EQ? (lambda (x) x) (lambda (y) y)) is false.
If EQ? does indeed say that the two identity procedures are different, then
we have an interesting example of Guy's "splitting" (which he claims to
dislike): both arguments are the identity procedure, and in all respects
they behave exactly the same except that EQ? says they're different. Now,
however, if I naively go through the semantics and make the changes implied
by the new domain equation for F, I find that implementations are *required*
to say that (EQ? (lambda (x) x) (lambda (y) y)) is false -- so splitting is
forced upon us. That naive semantics can be fixed, provided that we agree
on a precise formulation of the circumstances in which an implementation can
say that two procedures are EQ?. My suggestion that EQ? be left unspecified
on procedure values was prompted by a disagreement over precisely what those
circumstances should be. Since people don't like that, I now propose that
it's ok to say that two procedure values are EQ? iff the second components
(i.e., elements of E* --> K --> C) are equal. This is of course undecidable
in general but implementations should be allowed to take advantage of
whatever simple cases they can recognize. (I expect the MIT philosophy will
disagree.)
Similarly R must have a structure akin to R = L x (mathematical numbers),
but this isn't as troublesome because we seem to agree that it's ok for EQ?
to return true on numbers whenever the difference of the two numbers is
zero, and that EQ? must return false whenever the difference is nonzero.
I think the location-ridden semantics is uglier, but that's a matter of
taste. I admit that the location-ridden semantics doesn't affect compilers
provided my new suggestion is adopted (that EQ? can use the second component
of procedure values), because most of us were doing precisely the same thing
with the old semantics. If on the other hand optimizations such as those
raised by David Bartley are disallowed, then compilers are going to be less
effective. Furthermore the ambitious compilers will be more complex,
because they will still attempt those optimizations whenever the compiler
can prove that the procedures never get passed to the EQ? procedure. (To
the objection that the compiler could never prove such a thing because the
break key provides access to internals at arbitrary times, I reply that the
compiler has the freedom to define critical sections during which such
interrupts are deferred.)
----------------------------------------------------------------
Kent:
...I cite as precedent the case of CALL-WITH-CURRENT-CONTINUATION. Everyone
seemed to agree that it was easier to compile/optimize code which doesn't
allow returning these upward. The argument for pushing it through was not
that it made the implementation simpler, since in fact it complicated it. It
was instead the fact that it was (a) at least possible to implement and (b)
much simpler to some write programs when this feature was available. It
seems to me that the situation is similar for EQ? -- I do not want to give
up this feature. You (the compiler writer) have to solve this problem only
once. I (the programmer) will have to solve it repeatedly if you do not
solve it once for me.
Will:
First class escape procedures greatly simplified the semantics. Their
semantics is so beautiful you don't even have to see them. Downward-only
escape procedures have a really ugly semantics. The same holds for first
class procedures as opposed to downward-only procedures. Semantic
simplicity often does not correlate with implementational simplicity. My
complaint about the current definition of EQ? is not that it is hard to
implement -- it isn't -- but that I think its semantics are ugly. I haven't
always thought that -- I too once thought that (EQ? X X) should always be
true.
(I stand by my comment about semantic ugliness turning into compiler
complexity in this particular case, but in truth I said that for the sake of
people who think of me as a semantic purist who doesn't care about
implementations. If people now think of me as a hacker who doesn't care
about semantics, well, that's great, my disguise must be working.)
----------------------------------------------------------------
Guy:
....may two things that you might expect to be different turn out to be the
same? (Call this property "coalescence".) ....may one thing turn out to be
two different things? (Call this property "splitting".)
Will:
The problem is that we don't have a precise and independent definition of
what we mean by "expect to be different" and "one thing" until we have a
semantics for EQ?, so we can't use these notions to define EQ?. (Likewise,
when the RRRS says of certain objects that they "are identical to themselves
and are different from everything else...", it says nothing at all.) My
earlier reference to (EQ? (LAMBDA (X) X) (LAMBDA (Y) Y)) --> #!FALSE as a
splitting was intended in part to demonstrate that Guy's informal
distinction is probably based on some preconceived semantics for EQ?. That
would be ok if we could formalize that preconceived semantics and then
sanction particular classes of deviations from it, which is in effect what I
propose above.
----------------------------------------------------------------
Guy:
I feel that splitting is a semantically bad thing to have in a LISP-like
language, because I think name-reference should be free of side effects!
Will:
(EQ? + +) --> #!FALSE implies no more of a side effect than (EQ? 1000000
1000000) --> #!FALSE or (<? 3 3) --> #!FALSE or (+ 3 3) --> 6. All we're
talking about is the value returned by a procedure. Since procedures can't
be side effected, we can't look to the primitive mutators for guidance, and
we must fall back on the rule that indistinguishable objects should be EQ?.
----------------------------------------------------------------
Guy:
If two objects cannot be distinguished, then it should be legitimate to
merge them. If there are no RPLACA or RPLACD operations on CONS cells, then
hash-consing is a legitimate optimization (and, indeed, perhaps EQ should be
required to behave as EQUAL on CONS cells in the absence of such side
effects!)...
Will:
Hence (EQ? (LAMBDA (X) X) (LAMBDA (Y) Y)) --> #!TRUE should be ok, but we
can't require it (as we could for hashed pairs) because the problem is
undecidable. The challenge lies in writing a semantics that will allow it
but not require it. I have stated my belief that the cleanest such
semantics leaves EQ? unspecified on procedures, numbers, etc, but I am
willing to adopt what I believe is an uglier semantics if that's what people
want.
----------------------------------------------------------------
Gerry:
I think it is essential that (EQ? x x) be true of procedure values. We
should be able to think of compound data structures as LAMBDA calculus
entities (as at the end of section 3.3.1 of Abelson and Sussman -- "Mutation
is just assignment" -- p 207), and surely we want (EQ? x x) to be true of
CONSs (else assignment to components such as SET-CAR! will make no sense).
Will:
The lambda calculus has no side effects and no primitive or definable (in
the language) equality predicate that satisfies the rule that equal objects
are behaviorally indistinguishable. My feeling is that if the lambda
calculus can get along without EQ?, then Scheme should be able to get along
without it also except for those objects that can be stored into.
Nonetheless I think Gerry has expressed the best argument for making EQ? do
something reliable on procedures.
Let me observe, however, that the value of (LET ((FOO FOO)) (LAMBDA ARGS
(APPLY FOO ARGS))) is behaviorally identical to the value stored in FOO when
that value is a procedure object, but there is no similar way to take a pair
and get from it a behaviorally identical but non-EQ? pair without redefining
all the primitive operations on pairs. Thus if EQ? is supposed to express
something like total behavioral equivalence, then it does a much better job
with pairs than with procedures. Hence the argument for making EQ? work on
procedures is weaker than the corresponding argument for pairs.
In case anyone is worried, my proposal that EQ? can say that two procedure
values are identical whenever their E* --> K --> C parts are identical
is sufficient to ensure that
(EQ? (LET ((N 0)) (LAMBDA () (SET! N (1+ N)) N))
(LET ((N 0)) (LAMBDA () (SET! N (1+ N)) N)))
is false (ignoring the fact that a compiler could determine that neither
procedure is going anywhere). It would not guarantee that
(LET ((N 0))
(EQ? (LAMBDA () (SET! N (1+ N)) N)
(LAMBDA () (SET! N (1+ N)) N)))
is false (with the same caveat). In other words, my new proposal seems to
me to do the right thing with respect to object-oriented programming.
∂26-Nov-85 0953 @MIT-MC.ARPA:gls@THINK-AQUINAS.ARPA EQ? and procedures etc
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 26 Nov 85 09:41:30 PST
Received: from THINK-AQUINAS.ARPA by MIT-MC.ARPA 26 Nov 85 11:58:33 EST
Received: from FAUSTINUS.THINK.COM by THINK-AQUINAS.ARPA via CHAOS with CHAOS-MAIL id 2959; Tue 26-Nov-85 11:58:57-EST
Date: Tue, 26 Nov 85 11:57 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: EQ? and procedures etc
To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA,
RRRS-AUTHORS@MIT-MC.ARPA
cc: gls@THINK-AQUINAS.ARPA
In-Reply-To: The message of 25 Nov 85 19:29-EST from Will Clinger <willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA>
Message-ID: <851126115745.2.GLS@FAUSTINUS.THINK.COM>
Will has raised some very good points. I need to be more precise about
what I mean.
Will:
... Guy's informal
distinction is probably based on some preconceived semantics for EQ?. That
would be ok if we could formalize that preconceived semantics and then
sanction particular classes of deviations from it, which is in effect what I
propose above.
...
(EQ? + +) --> #!FALSE implies no more of a side effect than (EQ? 1000000
1000000) --> #!FALSE or (<? 3 3) --> #!FALSE or (+ 3 3) --> 6. All we're
talking about is the value returned by a procedure. Since procedures can't
be side effected, we can't look to the primitive mutators for guidance, and
we must fall back on the rule that indistinguishable objects should be EQ?.
Indeed, I have a preconceived semantics for EQ?, namely the semantics
attributed to "=" in logic: the identity function. A logic may have "="
in it or not, but it has to be included specially.
I view EQ? as a primitive notion: it is the very definition of what it
means for two things to be the same. I want other parts of the language
to satisfy certain relationships with respect to EQ?.
I define the notion of side effect in terms of EQ?. If I take two
formally identical computations (that is, expressions that are identical
in every way), and use them as the two arguments to EQ?, then if EQ?
returns #!FALSE I say that a side effect has occurred. (If EQ? returns
true then that result says nothing one way or the other about whether a
side effect has occurred.)
One of the properties I want in my language is that name-reference be
free of side effects. That is, if "x" is any name, I expect evaluation
of the form (EQ? x x) to produce #!TRUE.
Note that I have not yet insisted that (EQ? f f) return #!TRUE for any
kind of form f other than a name. In particular, I have not insisted
that
(EQ? (LAMBDA (X) X) (LAMBDA (X) X))
return #!TRUE. This is very different from saying that
(LET ((Z (LAMBDA (X) X))) (EQ? Z Z))
must return #!TRUE, and indeed I do insist on this latter case.
Note too that I do not insist that beta-conversion be a valid
transformation (and this is why we must be careful to distinguish
(EQ? (LAMBDA (X) X) (LAMBDA (X) X))
and
(LET ((Z (LAMBDA (X) X))) (EQ? Z Z)),
for example: we have not yet established substitutability of expressions
for names that represent their values). Rather, one of the requirements
for beta-conversion is that the resulting program fragment be externally
indistinguishable from the original with respect to side effects (as defined
above).
However, I do have a rule for LET: if x and y are two names (possibly
the same), then (LET ((x y)) (EQ? x y)) returns #!TRUE. (That is,
LET-binding does not "split". There is an analogous rule for binding of
LAMBDA-parameters. This rule can be generalized for arbitrary
side-effect-free expressions y.)
Once again, I insist that referring to a name be free of side effects.
It is also convenient to insist that referring to a constant (numbers
and quoted objects, for example) be free of side effect, but for now we
sidestep the question of whether the expression (+ 6 6) contains the
"same" constant 6 twice or two different constants representing the
mathematical value 6. I insist that the operation of function calling
per se be free of side effect; if evaluation of a function-call form has
a side effect, then necessarily either the body of the invoked function
has a side effect or one of the argument forms has a side effect. (This
is why I want references to constant to be side-effect-free: so that I
can claim that if (+ 6 6) has a side effect, it must be in the body of +
because it doesn't come from the references to the name + or to the
constant(s) 6.)
Now, what things in the language shall be permitted to have side
effects? We could consistently allow a call to + to result in a side
effect, with the result that (EQ? (+ 6 6) (+ 6 6)) might return #!FALSE.
(Since I so far allow the 6's to be distinct, perhaps it is more to the
point to say that (LET ((X 6)) (EQ? (+ X X) (+ X X))) might return
#!FALSE.) We could interpret this in familiar implementational terms by
saying that + allocates a new location associated with the result, but
the results do have the same mathematical values, and EQUAL? will
compare these values without regard to the location.
But because numerical equality is decidable we might as well say that
(EQ? m n) iff (EQUAL? m n) for numbers m and n and let it go at that.
Such a definition will maintain the desired properties of naming with
respect to EQ?.
On the other hand, because equality of functions is not decidable in
general, we cannot take such an easy way out. We insist that for two
functions f and g, (EQ? f g) must return #!FALSE if f and g are
operationally distinguishable (that is, if they have differences of
behavior that are detectable within the language). On the other hand,
it must be the case that (LET ((X f)) (EQ? x x)) returns #!TRUE for any
f, even a function. Consider the dilemma of poor EQ?: confronted with
two mathematical functions (for which operational equality is
undecidable in general), it could take the safe way out for the first
condition by returning #!FALSE if it can't decide, or it could take the
safe way out for the second condition by returning #!TRUE if it can't
decide; but it cannot do both. One solution, as Will has pointed out,
is to package a "hint" with every function object, in the form of a
"location". One should perhaps think of this not as indicating a
location in *memory*, in which the closure is somehow stored, but rather
as an indication of the *(dynamic) location in the code* whose
evaluation produced the function object. Two compare two closures,
then, one first compares the locations; if they match, then they
resulted from the same evaluation, and so EQ? must return #!TRUE to
satisfy the naming properties. Otherwise, EQ? looks at that
mathematical functions themselves; and it may return #!TRUE if it can
prove the functions are operationally indistinguishable, but it is
always safe to return #!FALSE in this case.
To summarize: I take EQ? as primitive; I define the notion of side
effect in terms of EQ?; I require the language to obey certain
properties defined in terms of EQ? (and this is why EQ? is special:
because structural properties of the language, such as naming, are
specified in terms of it); and I show that, because of the
undecidability of equality of functions, the use of pure mathematical
functions to represent closures results in a semantically inadequate
model because two requirements on the language cannot be satisfied
simultaneously by the implementation without additional information
(such as a location). So the use of locations is not a wart, but
critical to the semantics. Locations are not necessary for mathematical
objects whose equality is decidable, such as numbers.
Thus if EQ? is supposed to express
something like total behavioral equivalence, then it does a much better job
with pairs than with procedures. Hence the argument for making EQ? work on
procedures is weaker than the corresponding argument for pairs.
I propose that two things might happen to be behaviorally equivalent
without being EQ?. It is precisely because of the undecidability
problem that EQ? cannot determine equivalence; I say only that EQ?
returning #!TRUE implies behavioral equivalence. (This is why splitting
is bad: I might determine (EQ? X Y) => #!TRUE and later find that X and
Y behave differently, possibly only with respect to EQ? itsefl!)
In case anyone is worried, my proposal that EQ? can say that two procedure
values are identical whenever their E* --> K --> C parts are identical
is sufficient to ensure that
(EQ? (LET ((N 0)) (LAMBDA () (SET! N (1+ N)) N))
(LET ((N 0)) (LAMBDA () (SET! N (1+ N)) N)))
is false (ignoring the fact that a compiler could determine that neither
procedure is going anywhere). It would not guarantee that
(LET ((N 0))
(EQ? (LAMBDA () (SET! N (1+ N)) N)
(LAMBDA () (SET! N (1+ N)) N)))
is false (with the same caveat). In other words, my new proposal seems to
me to do the right thing with respect to object-oriented programming.
I think this is exactly right.
--Guy
∂26-Nov-85 1201 JAR@MIT-MC.ARPA EQV? and procedures etc
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 26 Nov 85 12:00:53 PST
Date: Tue, 26 Nov 85 15:03:10 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: EQV? and procedures etc
To: RRRS-AUTHORS@MIT-MC.ARPA
In-reply-to: Msg of 25 Nov 85 16:29:22 PST from Will Clinger <willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA>
Message-ID: <[MIT-MC.ARPA].733803.851126.JAR>
While we're stirring up the EQ? muck, I would like to stir up some EQV?
muck.
I would like it if the description of EQV? did NOT appeal to the
definition of EQ?. In fact, I would like it to be deterministic. That
is, while the meaning of (EQ? x y) is a function of an implementation,
the meaning of (CAR x) is not, and I would like EQV? to have the same
deterministic status as CAR.
A consequence of this is that unlike EQ?, the domain of EQV? would be
incomplete, that is, it might be an error to call it on certain
combinations of arguments. For example, if both arguments are
procedures, or both arguments are inexact numbers, it should be
undefined (and implementations are permitted to signal an error).
Examples: (EQV? 'A CAR) => false - different types
(EQV? (CONS 1 2) (CONS 1 2)) => false
(LET ((Z (FOO))) (EQV? Z Z)) => true
this would hold for any expression (FOO)
(EQV? (LAMBDA (X) X) (LAMBDA (Y) Y))
=> wrong - returning a consistent answer in all
implementations would impose horrible
constraints on implementations
(EQV? CAR CDR) => wrong - similarly
(EQV? #i1 #i1) => wrong - similarly
Of course, the exact behavior of EQV? in undefined situations is
unspecified; implementations may find it more efficient to fail to
detect domain errors than to detect them.
In other words, I want EQV? to strive to be the true mathematical
equality-of-denotation predicate which we would like to have but can't
(both for implementation and decidability reasons). It would
necessarily then have an incomplete domain.
If people seriously object to this I won't bother trying to make it more
precise; if they don't, and someone wants it to be made more precise,
I'll try to do so.
∂27-Nov-85 2057 @MIT-MC.ARPA:wagle%indiana.csnet@CSNET-RELAY.ARPA EQ? on pointers to functions
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 27 Nov 85 20:57:29 PST
Received: from CSNET-RELAY.ARPA by MIT-MC.ARPA 27 Nov 85 23:47:07 EST
Received: from indiana by csnet-relay.csnet id a015950; 27 Nov 85 23:29 EST
Date: Wed, 27 Nov 85 17:30:50 est
From: Perry Wagle <wagle%indiana.csnet@CSNET-RELAY.ARPA>
To: scheme%indiana.csnet@CSNET-RELAY.ARPA
Subject: EQ? on pointers to functions
re: the great EEEK! (I mean EQ?) debate, or
Is "(EQ? (call/cc (lambda (k) (k k))) (call/cc (lambda (k) k)))" true?
- - - - - - - - - - - - - - - - - - - - - - - - - - -
The generic LISP semantics I carry around in my head says that if an
expression terminates, it returns a pointer. The things pointers point to
have types (like "function", "integer", "string", etc).
Therefore my functionality equations are meta Will Clinger's equations.
That is, where he has "integer", I have "pointer to integer". As what I
deal with are pointers, my semantics are very simple if I ignore type. I
can well imagine that Will's semantics wants to barf when it tries to
incorporate the wierdness of EQ? on its level.
EQ? is very natural in my semantical domain. I resist "flattening" as
then we get Pascal, where we can't talk about eval, interpreters, and all
those powerful meta tools that made LISP better. Yeah, Pascal is simpler
and more tractable to our puny proof methods, but watching SCHEME backslide
to Pascal is horrifying to watch from here on the outside (I do CogSci).
- - - - - - - - - - - - - - - - - - - - - - - - - - -
The problem is not that you shouldn't have the type "pointer to function",
but that the collapsing of the same or different texts at different times to
an identical pointer is very complex and potentially unpredictable to a user
(unlike symbol or number collapsing). I don't see that this is cause to
spaz and declare EQ? undefined on pointers to functions, or to remove EQ?
altogether (?!?), as I can still write useful and correct programs that EQ?s
on pointers to functions. (I use ASSQ a lot).
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Proposal: Expressions that evaluate to a pointers to functions return
UNIQUE pointers. How this is done is up to the implementation. My
abstraction is that a function consists of a unique head, and a potentially
shared body. The head might be a cons cell with some sort of unique
timestamp in the CAR and a pointer to the body in the CDR, or the head might
be a box pointing to the body; these two methods would allow EQUAL? to work
on functions. Another way is the have the head be a "jump body" machine
instruction, but this would kill EQUAL?, though one could keep a pointer to
body in the type info of the function...
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Another proposal would be to be to have a way to tell the compiler that
"HEY!, this is a UNIQUE function, dammit! Don't you dare try to point
something else here!". This might be part of a more general facility to
prevent sharing of environment tails, etc.
- - - - - - - - - - - - - - - - - - - - - - - - - - -
I am trying more to be provocative here than "here's the solution!"ish.
∂04-Dec-85 1518 @MIT-MC.ARPA:msr@rice.ARPA Query: Scheme on a Sun?
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 4 Dec 85 15:18:10 PST
Received: from rice.ARPA by MIT-MC.ARPA 4 Dec 85 18:08:15 EST
Received: by rice.ARPA (AA28225); Wed, 4 Dec 85 17:01:38 CST
Date: Wed, 4 Dec 85 16:56:44 CST
From: Mark Riggle <msr@rice.ARPA>
Subject: Query: Scheme on a Sun?
To: scheme@mit-mc.ARPA
Message-Id: <168.msr.Dione@Rice>
Does anyone know of any good implementations of Scheme that runs on a
68000 Unix based workstation, specifically a Sun workstation?
Replies to msr@rice.arpa.
Many thanks.
∂12-Dec-85 1515 @MIT-MC.ARPA:gls@THINK-AQUINAS.ARPA [Postmaster@SCRC-STONY-BROOK.ARPA: Unable to deliver letter]
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 12 Dec 85 15:14:46 PST
Received: from GODOT.THINK.COM by MIT-MC.ARPA 12 Dec 85 17:24:40 EST
Received: from desiderius by GODOT.THINK.COM via CHAOS; Thu, 12 Dec 85 16:45:07 est
Date: Thu, 12 Dec 85 16:45 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: [Postmaster@SCRC-STONY-BROOK.ARPA: Unable to deliver letter]
To: KMP@SCRC-STONY-BROOK.ARPA
Cc: rrrs-authors@MIT-MC.ARPA, gls@THINK-AQUINAS.ARPA
In-Reply-To: <851209230127.8.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Message-Id: <851212164505.4.GLS@THINK-DESIDERIUS.ARPA>
[GLS -- This went to RRRS-AUTHORS and was explicitly CC'd to you but didn't
succeed in sending directly to you so I'm retrying; you may have
seen it already on RRRS-AUTHORS, but in case that failed, too, I'm
risking redundancy. -kmp]
Hmm, let me pose a few concrete examples to test that you and I agree.
You called this splitting:
[1] (LET ((X C) (Y C))
(EQ? X Y))
You and I seem to agree that evaluating this expression should always
yield true. Further, I suggest that the following are also in the same
category and assume that we both agree that these should -always- return
true as well:
[1a] (LET ((F (LAMBDA () C)))
(EQ? (F) (F)))
[1b] (LET ((F (LAMBDA () '(ANY EXPRESSION))))
(EQ? (F) (F)))
You called this coalescing:
[2] (LET ((F (LAMBDA () (LAMBDA () 3))))
(EQ? (F) (F)))
I agree with you that it is reasonable for either of {true,false} to be
returned from evaluating this. I suggest that the following are special
cases of the same situation, and that it may not be possible to predict
which of {true,false} will be returned:
[2a] (LET ((X '(ANY EXPRESSION))
(Y '(ANY EXPRESSION)))
(EQ? X Y))
[2b] (LET ((F (LAMBDA () '(ANY EXPRESSION)))
(G (LAMBDA () '(ANY EXPRESSION))))
(EQ? (F) (G)))
Among other things, 2b is important because of code constructed by
expressions like:
`(LET ((F (LAMBDA () ',EXP))
(G (LAMBDA () ',EXP)))
(EQ? (F) (G)))
We would like to constrain the semantics of the resulting expression to not
be perturbed by first writing the expression to an intermediate file and
then re-reading it.
Put another way -- with the exception of objects like symbols (which are
intentionally interned), sharing of memory should not affect the semantics
of an expression (though it may affect its perceived behavior). On the
other hand, certain identifiable patterns of data flow should be defined
to preserve sharing in a well-defined way, in order to ease certain
programming tasks and also (for not reasons that are not unrelated) to
allow various theorems, transformations, proofs, and optimizations to be
conveniently written about those patterns.
I agree with you in all these details.
--Guy
∂13-Dec-85 1355 @MIT-MC.ARPA:gls@THINK-AQUINAS.ARPA EQ? again, already
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 13 Dec 85 13:55:05 PST
Received: from GODOT.THINK.COM by MIT-MC.ARPA 13 Dec 85 16:34:33 EST
Received: from jehosephat by GODOT.THINK.COM via CHAOS; Fri, 13 Dec 85 16:31:46 est
Date: Fri, 13 Dec 85 16:31 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: EQ? again, already
To: rrrs-authors@MIT-MC.ARPA
Cc: gls@THINK-AQUINAS.ARPA
Message-Id: <851213163145.5.GLS@THINK-JEHOSEPHAT.ARPA>
From a message I received by papermail (for obscure reasons) from Will
Clinger, I infer that I may have confused a lot of people out there.
When I said that I take EQ? as my axiomatic notion of identity, I
neglected to say that I reject the further definition of EQ? in such
implementational terms as comparison of pointers. I expect EQ? to
behave more like EQV? (or like the Common Lisp EQL), so it might have
been more clear if I had used EQV? everywhere instead of EQ? in my last
long message. To put it another way, I constrain the meaning of my
identity operation by positing not only such requirements as that (EQ? X
X) always be true for X any name, but also that (EQ? (+ X Y) (+ X Y)),
(EQ? (* X Y) (* X Y)), and so on, so that numbers of the same type and
value are always EQ? (or EQV?, if you insist). I argued for changing
Common Lisp EQ to have the semantics EQL now has, but there was too much
implementation tradition behind EQ and so EQ remained unchanged. I feel
it is a mild pity that RRRS has made this same mistake.
--Guy
∂13-Dec-85 1850 JAR@MIT-MC.ARPA EQ? again, already
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 13 Dec 85 18:50:44 PST
Date: Fri, 13 Dec 85 21:53:08 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: EQ? again, already
To: gls@AQUINAS.THINK.COM
cc: RRRS-AUTHORS@MIT-MC.ARPA
In-reply-to: Msg of Fri 13 Dec 85 16:31 EST from Guy Steele <gls at THINK-AQUINAS.ARPA>
Message-ID: <[MIT-MC.ARPA].753457.851213.JAR>
Date: Fri, 13 Dec 85 16:31 EST
From: Guy Steele <gls at THINK-AQUINAS.ARPA>
I feel it is a mild pity that RRRS has made this same mistake.
If EQ? were banished to the realm of "implementation-dependent" and
satisfying few portable axioms (e.g. it could look at the machine state
when given two EQV? numbers), and EQV? were considered the portable
equality primitive, what would you have it do with procedures?
More importantly, I would like to see evaluation of LAMBDA-expressions
not be a side-effect, but not only is a contradictory assumption wired
into Abelson & Sussman's book (according to Sussman), the problem is
undecidable if by equality you mean what compilers would like equality
to mean, that is extensional equality ("f computes the same return value
and machine state as g given the same input arguments and machine
state"). Which would you prefer:
(a) to define EQV? to "be an error" when both arguments are procedures
(this implies that implementations would be encouraged to signal
errors, of course),
(b) to define LAMBDA to be a side-effect,
(c) to rule out optimizations which would inhibit "intensional"
comparison of procedures, or
(d) make EQV? to be implementation-dependent (and thus put it in the
same flea-bitten bag as EQ?)? I think those are the only alternatives.
Actually, now that I think of it, option (c), intensional procedure
comparison, could be made to work, conceivably. E.g. EQV? on two
procedures could use EQV? to compare bignums representing some canonical
form of the source (or object?) code (alpha- and maybe beta-converted to
some sort of normal form, and maybe other things) and the presumably
cons-cell-like cells which hold values of variables. Then indeed
(EQV? (LAMBDA (X) (LIST X Z)) (LAMBDA (Y) (LIST Y Z)))
would be defined to return true, and we could intern object code, do
CSE, and so on. I haven't though about this possibility, but I suspect
it would be very complicated to implement, and would inhibit some
important optimizations.
I echo my previous simple request (to which no one has replied - I guess
that everyone agrees): permit implementations of EQV? to signal an error
when given arguments that are both procedures.
∂13-Dec-85 1854 JAR@MIT-MC.ARPA EQ? again, already
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 13 Dec 85 18:54:08 PST
Date: Fri, 13 Dec 85 21:56:36 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: EQ? again, already
To: gls@AQUINAS.THINK.COM
cc: RRRS-AUTHORS@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].753459.851213.JAR>
Typo in previous message (result of electronic editing): flush the two
words "More importantly, ".
∂14-Dec-85 0603 @MIT-MC.ARPA:HAL@MIT-OZ intro computer science course at Brandeis
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 14 Dec 85 06:03:45 PST
Received: from MIT-OZ by MIT-MC.ARPA via Chaosnet; 14 DEC 85 08:25:33 EST
Date: Sat, 14 Dec 1985 08:22 EST
Message-ID: <HAL.12167035500.BABYL@MIT-OZ>
From: HAL%MIT-OZ@MIT-MC.ARPA
To: scheme@MIT-MC.ARPA
Subject: intro computer science course at Brandeis
This past semester, Brandeis University changed its introductory
computer science subject to use "Structure and Interpretation of
Computer Programs" and Scheme (running on Texas Instruments PCs).
The following essay is by Harry Mairson, who was in charge of the
subject.
\magnification = 1200
\centerline
{\bf Structure and Interpretation of Computer Programs}
\centerline{Autumn Semester, 1985}
\medskip
\centerline{\sl by Harry Mairson}
\bigskip
\bigskip
\parskip = 5pt plus1pt minus .5pt
This year, the Brandeis computer science department introduced a new
introductory course for its prospective majors. {\sl Structure and
Interpretation of Computer Programs}, a textbook and novel curriculum
under development at MIT for several years, replaced a standard course
teaching Pascal and modular programming. I taught the course in
cooperation with Harold Abelson, one of the MIT professors who
developed the curriculum. As the course comes to a conclusion this
term, I would like to make a few comments about its contents, and why
I believe it has been and will continue to be a success at Brandeis.
First of all, ``Structure and Interpretation of Computer Programs'' is
a sophisticated and high-powered course, presenting to students with
no presumed background in computer science an intensive introduction
to the subject of computation. Among the subjects presented in this
course are: induction and recursion, lambda calculus, actor models,
tail recursion, orders of growth, abstraction mechanisms, data-driven
and procedure-driven (i.e., ``message passing'') computation, data
structures, substitution and environment models of computation, stream
processing, applicative- and normal-order evaluation, how interpreters
and compilers work, and logic programming. All this as an {\sl
introduction} to computer science! I did not learn about many of these
subjects until I was in graduate school, and some I learned only while
teaching this innovative course.
Such an ambitious curriculum cannot succeed without a substantial
commitment of resources from both students and the University. Students
worked 15 to 20 hours a week on this course, sometimes more. The
computer science department bought 18 Texas Instruments Professional
Computers, with the latest version of the Scheme programming language that
was practically hot off the press; there were fewer than three students per
personal computer. Hal Abelson gave a two-hour master class each week.
I gave two one-hour recitation lectures, plus interminable tutorials.
(I had no fixed office hours, tried to be in as much as possible, and
students badgered me with questions constantly, sometimes until early
morning...) Three teaching assistants, Brandeis graduate students
Larry Bookman, Xiru Zhang, and Brandeis senior Moises Lejter ran
one-hour tutorials every week in groups of four to five students,
and worked as tutors in the laboratory. They were unflagging in their
dedication and patience. In addition, they were joined by three MIT
undergraduates, David Alcocer, Jos\'e Capo, and Scott Heeschen, providing
on-the-spot counseling and tutoring in the midst of programming crises.
The MIT students were great, but as I joked to them on their arrival,
``I'm delighted to have you help, and I can't wait to throw you out.''
Next year, Brandeis undergraduates will take their places.
The kids in the class knew every resource we could conceivably provide
them was there. Given that total commitment, they showed beyond any
doubt their own commitment and willingness to work real hard and absorb
the material.
This course has something new and profound to say about computation and
learning. With no time wasted, it immediately plunges into a discusssion
of the {\sl semantics} of computation, and treats almost peripherally
the questions of syntax. The importance of this approach can best be
explained by considering the difference between learning a foreign
language (say, French) and a computer language.
Before learning my first word of French, I already understood the semantics
of the language, since ``meaning'' means the same thing in English as it
does in French, despite any Gallic claims to the contrary: the French
talk about tables, chairs, families, taxes, good food, vacations; they use
the same verbs, adjectives, and adverbs as we do, and essentially the same
notions of time. So ``learning French'' meant learning a new grammar to
express the same ideas and thoughts I already knew how to express
in English.
The same cannot be said for learning a computer language, because there the
overriding questions of the {\sl d\'ebutant} are: what is the computer
doing, what {\sl can} it do, and what does my program {\sl mean?}
The grammar of any programming language is far simpler than that of
French; given enough compulsiveness, anyone can learn to make sure that all
the semicolons are in the right place, that for every {\tt BEGIN} there
is an {\tt END}, that left and right parentheses match. These grammatical
rules are annoying, but not conceptually deep.
It happens that this course is taught using the Scheme language, a dialect
of a more famous programming language called Lisp. But as the authors of
the text write, ``After a short time we forget about syntactic details
of the language (because there are none), and get on with the real issues.''
The Scheme language is used because it expresses easily a wide range of
computational processes, but these processes, and not the language itself,
are the centerpiece of this course.
Such an emphasis, as well as many other aspects of the course, is in
the best tradition of liberal education. The course is not simply a
compendium of ``current'' tricks of the programming trade that will
doubtless change in the next six months, but presents a foundation from
which today's and tomorrow's issues and controversies in computer science
can be understood and put into perspective. I expect this course will
teach students to think for themselves.
Computer science often attracts the ire of specialists in other academic
fields, principally physicists and mathematicians, but philosophers and
just about everyone else too, because it seems so narrow and self-referential
that it doesn't relate to other fields of study. This course goes a long
way to healing the wounds of that misconception, as well as teaching
students a healthy appreciation for the respective fields that are
not simply the ancestors of computer science, but its much needed partners
in the pursuit of knowledge and understanding. That means I want my
students to take lots of math, physics, and philosophy courses, and know
what these subjects are about!
For example, no discussion of the meaning of language can take place outside
the tradition of philosophy and its profound contribution to the understanding
of language. In the Scheme language, for example, the meaning of a simple
expression like {\tt (cons x y)} can be explored on many levels, none of them
artificial. The mechanism used by the computer to evaluate this expression
can be implemented in several ways that are substantially different:
{\tt (cons x y)} could be interpreted as a memory structure, an integer,
or a procedural abstraction. On the other hand, the expression has
precise meaning simply in its fixed use with respect to the other
constructs of the Scheme language.
I spent one lecture describing these two radically different points of
view, showing how the former view of ``meaning as implementation'' is the
direct descendant of logical atomism in the tradition of Bertrand Russell
and his followers, while the latter idea of ``meaning as use'' is a
natural consequence of the philosophy of language as proposed in the
later writings of Ludwig Wittgenstein. Similarly, in a discussion of the
so-called ``environment model'' of computation, the subject of denotation
is explored: we understand how classical problems of referential
transparency in language are resolved, and how conceptions of meaning and
time relate to each other. The semantics of computation becomes a
controlled laboratory where we can discover more about the complex
relationship of meaning and language.
Apart from the usual arithmetic programming examples, the course draws on
problems and examples from mathematics and physics. In one two-week problem
set, for example, the students implemented a video game called ``Lunar
Lander,'' where a spaceship with a fixed amount of fuel must be landed
under a gravitational force without crashing. In doing so, they experimented
with a variety of landing strategies. The principal goal of the problem set
is to teach the students how to use something called lambda expressions,
a programming language construct borrowed from mathematical logic. But the
problem set also makes the students think about models of physical reality,
where computation is not simply {\sl sui generis} but an analog of the
physical world. They implemented an optimal fuel-efficient landing
strategy, and I made them understand the ideas of calculus and elementary
physics that justifies calling the strategy optimal.
In other material developed in the course, methods of data structuring are
used to implement symbolic differentiation as in the differential calculus.
Stream processing provides a method for understanding integration, and
shows how the arithmetic of infinite power series can be automated. The
connections of these methods to the Macsyma system of ``symbolic
mathematics,'' a computer system of great use to researchers in science
and mathematics, are no mere coincidences.
Finally and most profoundly, the material presented in this course teaches
a wonder and respect for computation. It is true, as often repeated in that
hackneyed phrase, that computers only do what we tell them to. Stated
otherwise, a computational process evolves in a deterministic fashion from
an initial state, subject to fixed and mechanical constraints on the nature
of that evolution. But the potential richness, depth, and variety of that
evolution, as this course teaches, is truly mind-boggling. In the
introduction to their book, Harold Abelson and his co-author Gerald Jay
Sussman, also of MIT, write the following:
\bigskip
\item{}
We are about to study the idea of a {\sl computational process.}
Computational processes are abstract beings that inhabit computers. As
they evolve, processes manipulate other abstract things called {\sl data.}
The evolution of a process is directed by a pattern of rules called a
{\sl program.} People create programs to direct processes. In effect,
we conjure the spirits of the computer with our spells.
\item{}
A computational process is indeed much like a sorcerer's idea of a spirit.
It cannot be seen or touched. It is not composed of matter at all.
However, it is very real. It can perform intellectual work. It can
answer questions. It can affect the world by disbursing money at a bank
or by controlling a robot arm in a factory. The programs we use to conjure
processes are like a sorcerer's spells. They are carefully composed from
symbolic expressions in arcane and esoteric {\sl programming languages}
that prescribe the tasks that we want our processes to perform.
\item{}
A computational process, in a correctly working computer, executes programs
precisely and accurately. Thus, like the sorcerer's apprentice, the
novice programmer must learn to understand and to anticipate the
consequences of his conjuring.
\bigskip
In the same way that a biochemist marvels at DNA as a code that directs
the amazing growth and development of living organisms, I marvel as I watch
computer programs provide the code for the creation and interaction of
Abelson and Sussman's computational ``spirits.'' Just as
a chemist sees the elementary chemical building blocks
of nature interact, combine,
and recombine as she pours solutions together, the computer scientist
sees the rich and seemingly unpredictible interaction of computational
processes as a result of her procedural incantations.
For all those who have looked askance at the existence of computer science
in the university, Abelson and Sussman have written, ``Underlying our
approach to this subject is our conviction that `computer science' is
not a science and its significance has little to do with computers.
The computer revolution is a revolution in the way we think and in the way
we express what we think.''
I believe that nothing could be more exciting or more important at a
university than to understand the way we think and how we express those
thoughts. This new introductory course comes face-to-face with these profound
issues, and brings its students into the heart of the consequent
intellectual debate, sometimes pushing them to within striking distance
of the frontiers of research. I believe it will provide them with tools
to strike out on frontiers of their own, frontiers of personal discovery,
creativity, understanding and synthesizing of knowledge, driven on by
the powerful metaphors that the study of computational processes provide,
and by the personal intellectual success that this course provides them.
This new course demands a great commitment from its students and
teaching staff. Students have five official ``contact hours'' per
week with the teaching staff, and many more on an informal basis.
Because of that great contact, I believe that this course has another
thing to say that is also profound, though perhaps peripheral to the
issues of computation. The University is a place for teaching and
learning, not simply for the transmission of information. Teaching
and learning reinforce the respect, encouragement, and love that any
society or university needs to flourish. I hope this class says
loudly and clearly that students have a place in the crucial function
of this University, not as passive receivers of knowledge that spouts
from the end of a pedagogical assembly line, but as partners in an
important dialogue that defines what the University is.
I want the students in this class to have learned two things. First,
how much there is that they don't know. And second, that they can
learn anything they want. I hope that they will never forget the
former, and always be inspired by the latter. Every conceivable thing
was done in this course to provide a fertile and inspiring environment
for learning and discovery. What could students possibly do under
such circumstances but mature, grow, and learn?
The lesson for the teaching staff in this course is not so different.
While Newton said he saw further because he stood on the shoulders of
giants, I have always preferred Nietzsche's remark that a teacher is
poorly repaid if one only remains a student.
What a tremendous debt we teachers owe to those who nurtured us! We
honor those who taught us by nurturing students, and the way we
express that nurturing is to teach students to grow and think for
themselves, so they don't need us any longer. A friend of mine who is
a physician once said that the responsibility of a doctor is to love
your patients. I believe above all that the responsibility of a
teacher is to love your students, to show them what is known, and to
inspire them to confront the unknown. The territory is vast, and
because computer science is still so new, largely unexplored. The
rewards are great for those who simply press forward.
\bye
∂15-Dec-85 1641 JAR@MIT-MC.ARPA [CPH%MIT-OZ: HP 300s]
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 15 Dec 85 16:40:56 PST
Date: Sun, 15 Dec 85 19:42:55 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: [CPH%MIT-OZ: HP 300s]
To: SCHEME@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].755222.851215.JAR>
I'm forwarding this because I though it might be of general interest.
- Jonathan
Date: Thu, 12 Dec 1985 18:45 EST
From: CPH%MIT-OZ at MIT-MC.ARPA
To: KGK%Brown.CSNet at CSNET-RELAY.ARPA
Re: HP 300s
Have you people put Scheme on these putative ai machines yet?
As a matter of fact, would you know of any good source of information
for these machines? We just got a few and I may be the one to have to
figure out what they're good for. Like whether it's a research machine
or an educational machine, things like that.
We have yet to receive the remaining pieces of our model 320s, so I
suppose that the answer to your first question is no. However, within
several months we will undoubtedly have transferred all of our
implementation to them.
As for your other questions: we have alot of experience with the 200
series machines, which are reputed to be about half the speed of the
300 series. They seem to have adequate memory for some fairly big
programs, and with the compiler we are now using they run many
benchmarks within a factor of 3 or 4 of a 3600. So I would say that
they are very adequate for a number of research purposes, and much
more than adequate for educational purposes.
∂15-Dec-85 1919 JAR@MIT-MC.ARPA backquote
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 15 Dec 85 19:19:43 PST
Date: Sun, 15 Dec 85 22:22:11 EST
From: Jonathan A Rees <JAR@MIT-MC.ARPA>
Subject: backquote
To: ALAN@MIT-MC.ARPA, RRRS-AUTHORS@MIT-MC.ARPA
Message-ID: <[MIT-MC.ARPA].755421.851215.JAR>
Date: Sun, 15 Dec 85 06:10:14 EST
From: Alan Bawden <ALAN at MIT-MC.ARPA>
...
Also a minor point about your quasi-quote proposal: You notate the three
magic objects that are used for recognition as #!QUASIQUOTE, #!UNQUOTE and
#!UNQUOTE-SPLICE. I claim that in a language specification it would be
better to specify the names of three variables whose -values- are the three
magic markers. This is because it is dangerous for those objects to appear
directly as constants in source code. (In one message you point out this
danger yourself, I seem to remember.)
Instead of
(IF (EQ? (CAR FORM) '#!UNQUOTE-SPLICE) ...)
it is better to write
(IF (EQ? (CAR FORM) UNQUOTE-SPLICE-MARKER) ...).
And instead of
(DEFINE-READER-SYNTAX #/`
(LAMBDA (STREAM)
`(#!QUASIQUOTE ,(READ STREAM))))
(which doesn't work as intended) it is -certainly- better to write
(DEFINE-READER-SYNTAX #/`
(LAMBDA (STREAM)
`(,QUASIQUOTE-MARKER ,(READ STREAM)))).
In fact, I cannot imagine any situation in which I would want to type one
of the three magic markers directly. Conceivably a language specification
should specify how the quasi-quote marker -looks-, so that you can
recognize it if you happen to see it, but the user should not be encouraged
to risk typing it in himself. (Were I in charge I might consider
specifying the names of the three variables, what the objects look like
when PRINTed, and that is is an error if that printed representation is
ever seen by READ.)
I definitely agree with most of this (I have run into exactly this bug,
and I suspect other people have too). I only disagree with the
parenthetical remark at the end. I think it's important that the
markers, or at least forms so marked, be rereadable. One of the things
I was worried about was the problem of being able to print a program out
from one implementation and read it back in in another. One solution
would be for PRINT to generate ` - , - ,@ syntax properly, and have
isolated occurences of the markers print nonrereadably. Another
solution would be to require user code to always expand the backquote
form in some way before printing it, but that's unacceptable since your
target implementation might have some spiffy implementation of
backquote, and you'd like to be able to take advantage of it without
knowing what it is (or writing your own version of PRINT).
I tend to agree with Kent Dybvig's suggestion that the asymmetry with
QUOTE should be eliminated somehow. I suggested a long time ago,
certainly on one of the T mailing lists and probably to the RRRS
authors, that 'FOO should read DIFFERENTLY from the list (QUOTE FOO),
either as a list with a funny marker in its CAR or as an object of a
different datatype, but no one seemed to like that suggestion. Since
it's too late to change that, I think the markers should be symbols with
long names (no name is ever obscure enough, I know, but what can you
do?), since it's a pain both in some implementations and in the manual
to introduce new datatypes. We would then have to agree on what the
name is, so that users can be sure to avoid using it. Probably having
variables whose values are these symbols, or maybe even inventing little
S&ICP-style data abstractions (constructor, accessor, and predication
functions), is desirable too. But that would be redundant, not
bare-bones the way the rest of scheme is...
∂20-Dec-85 1153 @MC.LCS.MIT.EDU:CPH@OZ.AI.MIT.EDU Editors used with Scheme
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 20 Dec 85 11:43:11 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 20 DEC 85 14:22:18 EST
Date: Fri, 20 Dec 1985 14:17 EST
Message-ID: <CPH.12168673046.BABYL@MIT-OZ>
From: CPH%MIT-OZ@MIT-MC.ARPA
To: Duke Briscoe <duke@MITRE.ARPA>
Cc: SCHEME@MC.LCS.MIT.EDU
Subject: Editors used with Scheme
In-reply-to: Msg of 20 Dec 1985 13:37-EST from Duke Briscoe <duke at mitre.ARPA>
Folks around here seem to use Emacs almost exclusively. I think that
most people find it pretty adequate, although, not being familiar with
the Interlisp structure editor, I may not know what I'm missing.
Perhaps your Emacs is deficient? You mentioned mocklisp, which leads
me to believe that you are using Gosling Emacs. If you are using BSD
Unix, maybe you should try GNU Emacs, which is available free and is
the best Emacs there is (Stallman wrote it). If you try that and
still find it lacking, then perhaps Emacs implementors should make
some changes.
∂20-Dec-85 1153 @MC.LCS.MIT.EDU:duke@mitre.ARPA Editors used with Scheme
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 20 Dec 85 11:42:53 PST
Received: from mitre.ARPA by MC.LCS.MIT.EDU 20 Dec 85 13:38:08 EST
Full-Name: DUKE BRISCOE
Message-Id: <8512201837.AA03811@mitre.ARPA>
Organization: The MITRE Corp., Washington, D.C.
To: SCHEME@MIT-MC
Subject: Editors used with Scheme
Date: 20 Dec 85 13:37:37 EST (Fri)
From: Duke Briscoe <duke@mitre.ARPA>
I'm not very happy using my version of Emacs with Scheme, because of
deficiencies in the pretty printer and the general lack of commands
specialized for editing lisp. What I would like would be a structure
editor like the one in Interlisp, along with the necessary integration
with a file package. Does anybody have something like that? Is
everybody else using some version of Emacs or something similar? Does
somebody have some huge amount of mocklisp code to make Emacs comparable
to the Interlisp structure editor? I may attempt to put together a
structure editor in Scheme if I don't hear any satisfactory alternatives.
∂21-Jan-86 1150 @MC.LCS.MIT.EDU:marick%fang@gswd-vms Industrial-strength Scheme class.
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 21 Jan 86 11:50:30 PST
Received: from gswd-vms.ARPA by MC.LCS.MIT.EDU 21 Jan 86 14:48:47 EST
Received: from fang.GSD (fang.ARPA) by gswd-vms.ARPA (5.9/5.6)
id AA00332; Tue, 21 Jan 86 13:47:44 CST
Message-Id: <8601211947.AA00332@gswd-vms.ARPA>
Date: Tue, 21 Jan 86 13:45:09 cst
From: marick%fang@gswd-vms (Brian Marick)
To: scheme@mc.lcs.mit.edu
Subject: Industrial-strength Scheme class.
I am planning to teach a class in Scheme at work this summer. I'll be using
←Structure and Interpretation of Computer Programs← and Indiana's version of
Scheme. The people in the class will mostly be experienced C programmers,
along with a scattering of technical writers (with some Pascal experience)
and ex-programmers-now-managers. I'm teaching the class to expose these
people to new styles of programming, styles that (I hope) are becoming
increasingly important. I'm not an experienced teacher, though I have
taught such a classlet before.
Does anyone have any suggestions as to how I ought to go about this? What
should I skim over? What should I concentrate on? Does the book contain
too much or too little to be covered in a summer, considering that the people
are experienced but also have full-time-or-more jobs? How should I
supplement the book, and with what? Thanks.
Brian Marick
Gould CSD - Urbana
∂21-Jan-86 1446 @MC.LCS.MIT.EDU:HAL%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Industrial-strength Scheme class.
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 21 Jan 86 14:45:46 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 21 JAN 86 17:42:37 EST
Date: Tue, 21 Jan 1986 17:41 EST
Message-ID: <HAL.12177098817.BABYL@MIT-OZ>
From: HAL%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
To: marick%fang@GSWD-VMS.ARPA (Brian Marick)
Cc: scheme@MC.LCS.MIT.EDU
Subject: Industrial-strength Scheme class.
In-reply-to: Msg of 21 Jan 1986 14:45-EST from marick%fang at gswd-vms (Brian Marick)
MIT runs summer courses in this material for industry types. The
courses are two weeks of very intense full-time work. If I were you,
I'd be really nervous about teaching this to people who are
simultaneously holding full-time jobs. Given your goals, I would not
attempt to do more than the first 4 chapters.
It is VERY IMPORTANT that people do some programming, not just listen
to you lecture. Contact McGraw-Hill and get hold of Julie Sussman's
instructor's manual for the course, which has some problem-set
material.
Good luck.
∂23-Jan-86 1301 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: Industrial-strength Scheme class.
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 23 Jan 86 13:01:09 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 23 Jan 86 16:01:14 EST
Received: from indiana by csnet-relay.csnet id aj13046; 23 Jan 86 15:52 EST
Date: Thu, 23 Jan 86 15:45:07 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: scheme@mc.lcs.mit.edu
Subject: Re: Industrial-strength Scheme class.
I think you might do well to look at the new "Little Lisper", by
Dan Friedman and Matthias Felleisen. Every program seems to work
without modification in Chez Scheme, and I believe there is no
problem with other Schemes either (i.e., Scheme84, TIPC Scheme).
The Little Lisper starts out the way the old one did, teaching the
student about recursion, lists, etc. But the new edition also
covers first-class functions, even going so far as to introduce
a "by-value" Y-combinator. The code for a Scheme interpreter is
given in the book.
Assignments, continuations, and engines are not covered in the LL,
but that's alright since these topics are better left until after
you cover the material in the LL. You should definitely cover set!
after you get through the LL. As for continations and engines, I
find that people are able to pick up and enjoy engines in a short
time period, but that continuations confuse them. So if you have
extra time left over, I would definitely cover engines.
I think the LL is more suited to a short class than the A&S text;
for a longer class I would cover the LL first, then A&S. The LL
is also a "self-study" text, so that what you don't cover in class
the students can pick up easily on their own.
Dan may be able to tell you more about it (dfried@indiana). I'm
sure that SRA would send you a copy if you tell them what you need
it for.
Kent Dybvig
dyb.indiana@csnet-relay (CSNET)
...!ihnp4!iuvax!dyb (USENET)
∂24-Jan-86 0827 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA quasiquote implementation
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 24 Jan 86 08:27:35 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 24 Jan 86 10:49:26 EST
Received: from indiana by csnet-relay.csnet id a022299; 24 Jan 86 10:24 EST
Date: Fri, 24 Jan 86 01:01:14 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: rrrs-authors@mc.lcs.mit.edu
Subject: quasiquote implementation
Back when JAR first suggested making quasiquote standard, I transcribed
my quasiquote implementation from the C-coded reader into Scheme-coded
syntactic-extensions. I promised to send the code to David Bartley at
TI and figured some of the rest of you might be interested as well.
I believe that this gives different results from JAR's, because it can
actually fold up explicit calls to "list" and "list*" (for better or for
worse). It also insists that quasiquote, unquote, and unquote-splice
forms be well-formed, rather than ignoring those that aren't. As with
JAR's, nested quasiquotes work properly.
Because quasiquote and company are expanded at compile time rather than
read time, it is reasonable to write code that produces quasiquote forms.
"list*" (Common Lisp's name) is the same as JAR's "cons*". The meaning
of everything else should be obvious.
(let ((check
(lambda (x)
(unless (and (pair? (cdr x)) (null? (cddr x)))
(ferror (car x) "invalid form ~s" x)))))
(define-macro! quasiquote (x)
(recur f ((x x))
(cond
((not (pair? x)) `',x)
((eq? (car x) 'quasiquote) (check x) (f (f (cadr x))))
((eq? (car x) 'unquote) (check x) (cadr x))
((eq? (car x) 'unquote-splice)
(ferror 'unquote-splice "invalid context for ~s" x))
((and (pair? (car x)) (eq? (caar x) 'unquote-splice))
(check (car x))
(let ((d (f (cdr x))))
(if (equal? d '(quote ()))
(cadar x)
`(append ,(cadar x) ,d))))
(else
(let ((a (f (car x))) (d (f (cdr x))))
(if (pair? d)
(if (eq? (car d) 'quote)
(if (and (pair? a) (eq? (car a) 'quote))
`'(,(cadr a) . ,(cadr d))
(if (null? (cadr d))
`(list ,a)
`(list* ,a ,d)))
(if (memq (car d) '(list list*))
`(,(car d) ,a ,@(cdr d))
`(list* ,a ,d)))
`(list* ,a ,d))))))))
(define-macro! unquote (x)
(ferror 'unquote
"unquote form ,~s not valid outside of quasiquote"
x))
(define-macro! unquote-splice (x)
(ferror 'unquote
"unquote-splice form ,@~s not valid outside of quasiquote"
x))
∂24-Jan-86 1252 JAR@MC.LCS.MIT.EDU quasiquote implementation
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 24 Jan 86 12:52:38 PST
Date: Fri, 24 Jan 86 15:53:28 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: quasiquote implementation
To: dyb%indiana.csnet@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Fri 24 Jan 86 01:01:14 est from Kent Dybvig <dyb%indiana.csnet at CSNET-RELAY.ARPA>
Message-ID: <[MC.LCS.MIT.EDU].794952.860124.JAR>
Your implementation, which is very similar to the T and MIT Scheme
quasiquote imeplementations, has the powerful advantage over mine of
conciseness, but it has the serious flaw that it makes the expansion of
nested quasiquote forms visible to the user, thus making it difficult to
write portable code to manipulates such forms. For example, (EQUAL?
'`(A ,B) ``(A ,B)) doesn't hold in your implementation. This seems to
defeat my original aim in suggesting that we standardize the external
syntax of `, which was to allow people to write portable
program-manipulating programs.
Jonathan
∂25-Jan-86 1155 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: quasiquote implementation
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Jan 86 11:55:21 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 25 Jan 86 14:56:07 EST
Received: from indiana by csnet-relay.csnet id aa06542; 25 Jan 86 14:34 EST
Date: Sat, 25 Jan 86 13:04:04 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: JAR@mc.lcs.mit.edu
Subject: Re: quasiquote implementation
Cc: rrrs-authors@mc.lcs.mit.edu
Your implementation, which is very similar to the T and MIT Scheme
quasiquote imeplementations, has the powerful advantage over mine of
conciseness, but it has the serious flaw that it makes the expansion of
nested quasiquote forms visible to the user, thus making it difficult to
write portable code to manipulates such forms. For example, (EQUAL?
'`(A ,B) ``(A ,B)) doesn't hold in your implementation. This seems to
defeat my original aim in suggesting that we standardize the external
syntax of `, which was to allow people to write portable
program-manipulating programs.
Jonathan
Yes, I see what you mean. My goal in making the forms standardized
was to to allow portable code such as an interpreter to make sense
out of what the function "read" returns, and also to provide for the
proper pretty-printing of source programs. I hadn't thought of the
double-quasiquote issue. When I read your first article, I thought
that you wanted
'`(A ,B) = ``(A ,B) => (list (quote a) b)
which is relatively easy (but not desirable, since I didn't want to
reach inside the quote). Instead, I see you want
'`(A ,B) = ``(A ,B) => `(A ,B)
which I can certainly sympathize with. This explains the need for
the "level" variable in your code. For anyone who cares, here is
another (less powerful) version of my code with a level-tracking
argument added. I have tested it only briefly.
(let ((check
(lambda (x)
(unless (and (pair? (cdr x)) (null? (cddr x)))
(ferror (car x) "invalid form ~s" x))))
(quasicons
(lambda (a d)
(if (pair? d)
(if (eq? (car d) 'quote)
(if (and (pair? a) (eq? (car a) 'quote))
`'(,(cadr a) . ,(cadr d))
(if (null? (cadr d))
`(list ,a)
`(list* ,a ,d)))
(if (memq (car d) '(list list*))
`(,(car d) ,a ,@(cdr d))
`(list* ,a ,d)))
`(list* ,a ,d)))))
(define-macro! quasiquote (x)
(recur f ((x x) (n 0))
(cond
((not (pair? x)) `',x)
((eq? (car x) 'quasiquote)
(check x)
(quasicons ''quasiquote (f (cdr x) (1+ n))))
((eq? (car x) 'unquote)
(check x)
(if (zero? n)
(cadr x)
(quasicons ''unquote (f (cdr x) (1- n)))))
((eq? (car x) 'unquote-splice)
(check x)
(if (zero? n)
(ferror 'unquote-splice "invalid context for ,@~s" (cadr x))
(quasicons ''unquote-splice (f (cdr x) (1- n)))))
((and (zero? n) (pair? (car x)) (eq? (caar x) 'unquote-splice))
(check (car x))
(let ((d (f (cdr x) n)))
(if (equal? d '(quote ()))
(cadar x)
`(append ,(cadar x) ,d))))
(else (quasicons (f (car x) n) (f (cdr x) n)))))))
(define-macro! unquote (x)
(ferror 'unquote
"unquote form ,~s not valid outside of quasiquote"
x))
(define-macro! unquote-splice (x)
(ferror 'unquote
"unquote-splice form ,@~s not valid outside of quasiquote"
x))
∂28-Jan-86 1108 @MC.LCS.MIT.EDU:ram%YALE-RING@YALE.ARPA Of growing code and diminishing hacks...
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 28 Jan 86 10:52:57 PST
Received: from yale by MC.LCS.MIT.EDU 28 Jan 86 13:47:21 EST
Received: by Yale-Bulldog.YALE.ARPA; 28 Jan 86 06:22:59 EST (Tue)
Date: 28 Jan 86 06:22:59 EST (Tue)
From: <ram%YALE-RING@YALE.ARPA>
Message-Id: <8601281122.AA16563@Yale-Bulldog.YALE.ARPA>
Subject: Of growing code and diminishing hacks...
To: t-discussion@YALE.ARPA, scheme@mit-mc.arpa
A SHORT BALLAD DEDICATED TO THE GROWTH OF PROGRAMS
==================================================
by
Ashwin Ram
This is a tale of a sorry quest
To master pure code at the T guru's behest
I enrolled in a class that appealing did seem
For it promised to teach fine things like T3 and Scheme
The first day went fine; we learned of cells
And symbols and lists and functions as well
Lisp I had mastered and excited was I
For to master T3 my hackstincts did cry
I sailed through the first week with no problems at all
And I even said "closure" instead of "function call"
Then said the master that ready were we
To start real hacking instead of simple theory
Will you, said he, write me a function please
That in lists would associate values with keys
I went home and turned on my trusty Apollo
And wrote a function whose definition follows:
(cdr (assq key a-list))
A one-liner I thought, fool that I was
Just two simple calls without a COND clause
But when I tried this function to run
CDR didn't think that NIL was much fun
So I tried again like the good King of yore
And of code I easily generated some more:
(cond ((assq key a-list) => cdr))
It got longer but purer, and it wasn't too bad
But then COND ran out and that was quite sad
Well, that isn't hard to fix, I was told
Just write some more code, my son, be bold
Being young, not even a moment did I pause
I stifled my instincts and added a clause
(cond ((assq key a-list) => cdr)
(else nil))
Sometimes this worked and sometimes it broke
I debugged and prayed and even had a stroke
Many a guru tried valiantly to help
But undefined datums their efforts did squelch.
I returneth once more to the great sage of T
For no way out of the dilemma I could see
He said it was easy -- more lines must I fill
with code, for FALSE was no longer NIL.
(let ((val (assq key a-list)))
(cond (val (cdr val))
(else nil)))
You'd think by now I might be nearing the end
Of my ballad which seems bad things to portend
You'd think that we could all go home scot-free
But COND eschewed VAL; it wanted #T
So I went back to the master and appealed once again
I said, pardon me, but now I'm really insane
He said, no you're not really going out of your head
Instead of just VAL, you must use NOT NULL instead
(let ((val (assq key a-list)))
(cond ((not (null? val)) (cdr val))
(else nil)))
My song is over and I'm going home to bed
With this ineffable feeling that I've been misled
And just in case my point you have missed
Somehow I preferred (CDR (ASSQ KEY A-LIST))
:-)
==================================================
-------
∂28-Jan-86 2352 @MC.LCS.MIT.EDU:Miller.pa@Xerox.COM Re: Of growing code and diminishing hacks...
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 28 Jan 86 23:52:17 PST
Received: from Xerox.COM by MC.LCS.MIT.EDU 29 Jan 86 02:52:42 EST
Received: from Cabernet.ms by ArpaGateway.ms ; 28 JAN 86 23:49:12 PST
Date: 28 Jan 86 23:36 PST
From: Miller.pa@Xerox.COM
Subject: Re: Of growing code and diminishing hacks...
In-reply-to: <ram%YALE-RING@YALE.ARPA>'s message of 28 Jan 86 06:22:59
EST (Tue)
To: ram%YALE-RING@YALE.ARPA
cc: t-discussion@YALE.ARPA, scheme@MC.LCS.MIT.EDU
Message-ID: <860128-234912-1014@Xerox>
(define (overloaded-cdr val)
(if (null? val) nil (cdr val)))
(overloaded-cdr (assq key a-list))
In other words, if you want a cdr that horribly overloads nil, then
write one. As for me, I think of a cons cell as an object with car and
cdr fields in it, just as a point is an object with x and y fields in
it. How about:
(define (overloaded-x point)
(if (null? point) nil (x point)))
∂29-Jan-86 0121 @MC.LCS.MIT.EDU:Miller.pa@Xerox.COM Re: Of growing code and diminishing hacks...
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Jan 86 01:21:31 PST
Received: from Xerox.COM by MC.LCS.MIT.EDU 29 Jan 86 04:21:45 EST
Received: from Salvador.ms by ArpaGateway.ms ; 29 JAN 86 01:20:42 PST
Date: 29 Jan 86 01:14 PST
From: Miller.pa@Xerox.COM
Subject: Re: Of growing code and diminishing hacks...
In-reply-to: <ram%YALE-RING@YALE.ARPA>'s message of 28 Jan 86 06:22:59
EST (Tue)
To: ram%YALE-RING@YALE.ARPA
cc: t-discussion@YALE.ARPA, scheme@MC.LCS.MIT.EDU
Message-ID: <860129-012042-1051@Xerox>
And another thing. The only reason NIL == #F usually works out so well
in lisps is that the most common domain of concern is lists. In both C
and APL, FALSE == 0 since a very common domain of concern is numbers.
Hopefully we are moving towards a programming style that is more
abstract datatype or object based, and so the primacy of lists will
diminish. In any case, I don't want my programming language prejudging
for me what types of object should be my major concern, and compromising
its foundations to optimize for that one type.
∂29-Jan-86 0558 GJC@MC.LCS.MIT.EDU Overloading of empty list as false.
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Jan 86 05:58:17 PST
Date: Wed, 29 Jan 86 08:58:51 EST
From: "George J. Carrette" <GJC@MC.LCS.MIT.EDU>
Subject: Overloading of empty list as false.
To: Miller.pa@XEROX.COM
cc: SCHEME@MC.LCS.MIT.EDU, t-discussion@YALE.ARPA,
ram@YALE-RING.ARPA
In-reply-to: Msg of 29 Jan 86 01:14 PST from Miller.pa at Xerox.COM
Message-ID: <[MC.LCS.MIT.EDU].800287.860129.GJC>
The primacy of lists in lisp is due to the fact that lisp is its own
meta language and the vocabulary of that meta language is constructed
inductively from lists, symbols and other constants. Furthermore, the
most general graphs can be constuctured entirely in terms of
bifurcations represented as cons cells; and bifurcations have a
primacy over trifurcations etc. Topping this off by using the logical falsity
constant as the token to mark the end of certain kinds of graphs is
entirely natural definition to use.
The lists themeselves will remain in their primacy as a prefered construct of
efficient assembly language programming, (especially if this means your
assembly language is LISP on a LISPMACHINE). Take note Plummer's multilisp
emulator that he implemented on the 3600: Comments in the code indicating that
using (SETQ *STACK* (CONS ELEMENT *STACK*)) was more efficient than
using the C/FORTRAN/PASCAL style INDEX plus ARRAY, because the GC overhead
was smaller than the expense of the extra instructions and memory references
needed to manipulate the more complicated data structure.
But I am arguing the barn door closed after the cows have left.
The recent slant of revised-revised-report-on-scheme has
indeed cleaned up things to make them more acceptable to the
general community; throwing out all the obvious meta language
machinery and with it much of the preference for lists.
The reason that FALSE == 0 in C is not due to the concern for the domain
of numbers. (Since in C one will often mark the end of character strings
with 0, and represent the NULL pointer as 0 also). FALSE == 0 because
of the instruction sets and memory organizations of the machines
on which C was developed. Similarly in PDP10 Maclisp and CADR Lispmachine
NIL == 0 (as a machine location address).
∂29-Jan-86 1049 @MC.LCS.MIT.EDU:ram%YALE-RING@YALE.ARPA Re: Of growing code and diminishing hacks...
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Jan 86 10:49:09 PST
Received: from yale by MC.LCS.MIT.EDU 29 Jan 86 13:05:55 EST
Received: by Yale-Bulldog.YALE.ARPA; 29 Jan 86 09:39:05 EST (Wed)
Date: 29 Jan 86 09:39:05 EST (Wed)
From: <ram%YALE-RING@YALE.ARPA>
Message-Id: <8601291439.AA10931@Yale-Bulldog.YALE.ARPA>
Subject: Re: Of growing code and diminishing hacks...
To: <Miller.pa@Xerox.COM>
Cc: t-discussion@YALE.ARPA, scheme@mit-mc.arpa
In-Reply-To: <Miller.pa@Xerox.COM>, 28 Jan 86 23:36 PST
(define (overloaded-cdr val)
(if (null? val) nil (cdr val)))
(overloaded-cdr (assq key a-list))
In other words, if you want a cdr that horribly overloads nil, then
write one. As for me, I think of a cons cell as an object with car and
cdr fields in it, just as a point is an object with x and y fields in
it. How about:
(define (overloaded-x point)
(if (null? point) nil (x point)))
So now we have a proliferation of functions. You could just as well think
of CAR and CDR as operations, and NIL as an object that handles them by
returning NIL. Much cleaner. Well, maybe not; I guess that's debatable. I
think the code is cleaner even though the semantics that the compiler must
implement may become a little hairier. But that's what compilers are for
:-).
-------
∂29-Jan-86 1119 @MC.LCS.MIT.EDU:ram%YALE-RING@YALE.ARPA Re: Of growing code and diminishing hacks...
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Jan 86 11:19:22 PST
Received: from yale by MC.LCS.MIT.EDU 29 Jan 86 13:19:18 EST
Received: by Yale-Bulldog.YALE.ARPA; 29 Jan 86 09:49:57 EST (Wed)
Date: 29 Jan 86 09:49:57 EST (Wed)
From: <ram%YALE-RING@YALE.ARPA>
Message-Id: <8601291449.AA11227@Yale-Bulldog.YALE.ARPA>
Subject: Re: Of growing code and diminishing hacks...
To: <Miller.pa@Xerox.COM>
Cc: t-discussion@YALE.ARPA, scheme@mit-mc.arpa
In-Reply-To: <Miller.pa@Xerox.COM>, 29 Jan 86 01:14 PST
And another thing. The only reason NIL == #F usually works out so well
in lisps is that the most common domain of concern is lists. In both C
and APL, FALSE == 0 since a very common domain of concern is numbers.
I didn't say that NIL was in any way the best choice for FALSE across all
languages. In Lisps, NIL = #F is just as reasonable as 0 = FALSE in C or
APL. Try telling a C programmer that 0 won't be FALSE anymore.
-------
∂11-Feb-86 0420 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Which constants must be quoted?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 11 Feb 86 04:20:06 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 11 Feb 86 07:21:20 EST
Received: from tektronix by csnet-relay.csnet id ad18218; 11 Feb 86 6:45 EST
From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
To: kend%tekla.uucp@CSNET-RELAY.ARPA, RRRS-AUTHORS@mc.lcs.mit.edu
Cc: willc%tektronix.csnet@CSNET-RELAY.ARPA
Received: from tekchips by tektronix with smtp ; 10 Feb 86 10:24:39 PST
Comment: Message received over unauthenticated port at tektronix
Received: by tekchips (5.31/5.14), id AA04677; Mon, 10 Feb 86 10:25:22 PST
Message-Id: <8602101825.AA04677@tekchips>
Subject: Which constants must be quoted?
In-Reply-To: Your message of 10 Feb 86 09:10:50 PST (Mon)., <8602101710.AA23029@tekla>
Date: 10 Feb 86 10:25:17 PST (Mon)
I (Will Clinger) received the following from Ken Dickey of Tektronix:
----------------------------------------------------------------
Will,
The Revised Revised Report is somewhat ambiguous on what
computational objects are self evaluating. For example the grammar
on page 7 does not list <char> as a constant, but there is a
statement in section II.7 that with the "#\" notation characters are
self evaluating. Likewise both character and vector constants are
mentioned as self evaluating on page 12 (under quote), but section
II.9, on vectors, does not state whether vectors (which use the "#("
notation) are self evaluating. [Note that the T manual I have does
not state whether vectors are self evaluating either].
It would seem that any object denoted by the sharp would tend by
usage to be self evaluating ("constant"). However, this is nowhere
stated and the comments on page 6 (Other notations) seem to indicate
that # is or may be simply a read macro.
The specific question I started out with is "Are vectors self evaluating?".
Are they? Also, are characters always self evaluating, or is this strictly
connected with the "#\" notation?
Pax & Thanks,
-Somewhat Confused (tekla!kend)
----------------------------------------------------------------
I am a little confused also, but here's what I think happened. After
Brandeis, TI requested over the net that characters written in the #\
notation should be guaranteed to evaluate to themselves, and no one
objected. I forgot to change the grammar on page 7 or to mention
characters on page 12.
As for vectors, I think we decided not to decide at Brandeis, and so the
draft I sent off to MIT did not mention characters or vectors on page
12. They were added at MIT as part of the final editing performed (I
assume) by Gerry Sussman and Hal Abelson..
I agree with the change, but some might question the decision on vectors.
There seem to be approximately two principled answers to the question of
which values must be quoted (answer 1: everything; answer 2: only symbols
and nonempty lists). Any other answer will include arbitrary distinctions,
about which no definitive argument can be made.
I'll send your message and this reply on to RRRS-AUTHORS@MIT-MC. The
inconsistencies you pointed out should be fixed.
Peace, Will Clinger
willc@tekronix.csnet
∂12-Feb-86 1803 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Which constants must be quoted?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 12 Feb 86 18:03:34 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 12 FEB 86 19:43:43 EST
Date: Wed, 12 Feb 1986 19:38 EST
Message-ID: <CPH.12182887323.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
Cc: kend%tekla.uucp@CSNET-RELAY.ARPA, RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: Which constants must be quoted?
In-reply-to: Msg of 10 Feb 1986 13:25-EST from willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
I would like to suggest: quoting should be necessary only for symbols
and lists (including the empty list.) My reasoning:
1. Only symbols and lists can represent non-constant s-expressions.
Therefore it is not necessary to quote other objects.
2. While there is definitely a split of opinion on whether or not the
remaining objects should require quoting (i.e. should we try to be
more like 3-lisp or not,) I favor not requiring quoting since this is
traditional lisp practice. I don't see that such a decision affects
the semantics of the language much, so there seems little reason to
break with tradition here (not to mention the fact that I have a
considerable investment in this tradition!)
3. I favor quoting the empty list, because I don't think that it
should be distinguished from lists in general. As RRRS states, the
unquoted empty list represents an empty combination, and should be
considered an error.
∂13-Feb-86 1147 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: Which constants must be quoted?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 13 Feb 86 11:47:15 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 13 Feb 86 14:48:43 EST
Received: from indiana by csnet-relay.csnet id a014137; 13 Feb 86 14:34 EST
Date: Thu, 13 Feb 86 12:30:07 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: cph@oz.ai.mit.edu
Subject: Re: Which constants must be quoted?
Cc: RRRS-AUTHORS@mc.lcs.mit.edu, kend%tekla.uucp@csnet-relay.arpa
I agree with all your comments except the rationale for quoting the
empty list. There is no such thing as an "empty combination", the
RRRS not withstanding.
There is a practical reason for allowing unquoted (). If #!null
and #!false are just reader syntax for (), then requiring a quote
on () is tantamount to requiring a quote on #!null and #!false
(this is especially bothersome within the code for a syntactic
extension or other program transformation, where two quotes are
required to produce a quoted () in the expansion).
On the other hand, there sems to be no practical reason to require
the quote. I can think of only two valid reasons to require the
quote: (1) to simplify the semantics of the language, or (2) to
allow the compiler to catch a common programming error. I don't
believe either reason applies here.
Perhaps () should be recognized as the "empty special form" rather
than the "empty combination". Of course, the empty special form
always evaluates to ().
Kent
∂13-Feb-86 1257 JAR@MC.LCS.MIT.EDU Which constants must be quoted?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 13 Feb 86 12:57:10 PST
Date: Thu, 13 Feb 86 15:58:41 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: Which constants must be quoted?
To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU, kend%tekla.uucp@CSNET-RELAY.ARPA,
willc%tektronix.csnet@CSNET-RELAY.ARPA
In-reply-to: Msg of 10 Feb 86 10:25:17 PST (Mon) from willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
Message-ID: <[MC.LCS.MIT.EDU].817505.860213.JAR>
Date: 10 Feb 86 10:25:17 PST (Mon)
From: willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
...
As for vectors, I think we decided not to decide at Brandeis, and so the
draft I sent off to MIT did not mention characters or vectors on page
12. They were added at MIT as part of the final editing performed (I
assume) by Gerry Sussman and Hal Abelson..
I agree with the change, but some might question the decision on vectors.
There seem to be approximately two principled answers to the question of
which values must be quoted (answer 1: everything; answer 2: only symbols
and nonempty lists). Any other answer will include arbitrary distinctions,
about which no definitive argument can be made.
I think that I and other people associated with T are the holdouts here.
In a language based on evaluation instead of normalization, answer 1 is
the "right thing," but unfortunately, if we're to be Lisp-like, we
should permit omitting the ' in the case of numbers and strings. 2 is
unacceptable because it makes the class of permissible programs larger
than necessary, and therefore reduces opportunities for error checking.
For example, suppose there's a bug in a macro, and it returns a closure
instead of a lambda-exparession. Or suppose that due to an FTP or
editor bug, or even a typo, a stray # was inserted into a source file
just before a parenthesis. These situations would be very difficult to
debug if closures and vectors were legitimate expressions.
So I think that an intermediate position between 2 and 3 *can* be
justified by the principle of Occam's razor, and we should disallow
self-evaluation of vectors, procedures, and other "random" objects
because it's unnecessary. That is, the class of legitimate programs
should be as small as is reasonable. Programming language tradition has
numbers and strings self-evaluating; everything else is dubious. In the
case of composite objects like vectors and procedures, we should not
lock out the future possibility that a meaning other than
self-evaluation might be assigned in the future. For example, I don't
see any a priori reason why vectors should be treated differently from
lists; seems to me that #(CAR '(A B)) has as much right as (CAR '(A B))
to evaluate to A. Similarly, perhaps a procedure would want to be
invoked (or "sent a message"?) to produce a value.
I don't care much about booleans and characters; they could go either
way as far as I'm concerned. I guess I only advise updating the manual
to state clearly that characters self-evaluate.
It is true that distinctions become arbitrary here, but in each case we
can apply judgement the same way that we applied judgement in the
inclusion of any language feature. I think it's hoping for too much to
look for definitive arguments; much of the language would suffer
severely under such scrutiny.
I disagree with Chris's statement that it is "Lisp tradition" for random
objects to self-evaluate. I have seen messages like #73556 UNEVALUABLE
DATUM in Maclisp and other dialects more times than I can remember, and
I have always been happy to see them, because they have always put me on
the road to eliminating yet one more bug.
Jonathan.
∂14-Feb-86 0711 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Which constants must be quoted?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 14 Feb 86 07:10:51 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 14 FEB 86 10:12:21 EST
Date: Fri, 14 Feb 1986 10:03 EST
Message-ID: <CPH.12183306912.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: kend%tekla.uucp@CSNET-RELAY.ARPA, RRRS-AUTHORS@MC.LCS.MIT.EDU,
willc%tektronix.csnet@CSNET-RELAY.ARPA
Subject: Which constants must be quoted?
In-reply-to: Msg of 13 Feb 1986 15:58-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
Date: Thursday, 13 February 1986 15:58-EST
From: Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
So I think that an intermediate position between 2 and 3 *can* be
justified by the principle of Occam's razor, and we should disallow
self-evaluation of vectors, procedures, and other "random" objects
because it's unnecessary. That is, the class of legitimate programs
should be as small as is reasonable.
I disagree with Chris's statement that it is "Lisp tradition" for random
objects to self-evaluate.
I agree with you about this -- I wasn't thinking about objects like
procedures and such. In fact, when I wrote that I had in mind only
objects for which there is read syntax, specifically: lists, symbols,
vectors, strings, characters, numbers, and booleans. I believe that
tradition does conform to my statement with this restriction. All of
the other things should cause errors, as you seem to suggest.
I don't care whether vectors are self-evaluating, but I think that
strings and numbers should be. As for characters and booleans: I
prefer that they self-evaluate, because I use them often and there
seems no very good reason to require that they be quoted.
∂14-Feb-86 0944 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Which constants must be quoted?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 14 Feb 86 09:44:42 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 14 FEB 86 12:35:28 EST
Date: 14 Feb 1986 12:30 EST (Fri)
Message-ID: <JINX.12183333605.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
Cc: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>, kend%tekla.uucp@CSNET-RELAY.ARPA,
RRRS-AUTHORS@MC.LCS.MIT.EDU, willc%tektronix.csnet@CSNET-RELAY.ARPA
Subject: Which constants must be quoted?
In-reply-to: Msg of 14 Feb 1986 10:03-EST from CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU
I don't think vectors should self-evaluate:
I think that making back-quote (comma) work with them would
be very useful:
`#(1 2 3 ,x 4 5 ,y) equivalent to (vector 1 2 3 x 4 5 y)
It would be somewhat weird if the above were true but #(1 2 3 4 5)
required no quoting.
∂14-Feb-86 1638 @MC.LCS.MIT.EDU:KMP@SCRC-STONY-BROOK.ARPA Which constants must be quoted?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 14 Feb 86 16:37:47 PST
Received: from SCRC-STONY-BROOK.ARPA by MC.LCS.MIT.EDU 14 Feb 86 19:39:03 EST
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 417951; Fri 14-Feb-86 19:36:23-EST
Date: Fri, 14 Feb 86 19:37 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: Which constants must be quoted?
To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
cc: KMP@SCRC-STONY-BROOK.ARPA, JAR@MIT-MC.ARPA,
RRRS-AUTHORS@MC.LCS.MIT.EDU, kend%tekla.uucp@CSNET-RELAY.ARPA
In-Reply-To: <[MC.LCS.MIT.EDU].817505.860213.JAR>
Message-ID: <860214193710.4.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
I agree with Jonathan that unevaluable data errors are useful in debugging and
we shouldn't define all random objects to self-evaluate or we'll just delay
the error-detection process to no good end.
For cleanliness reasons, I wish we could make numbers, etc. not self-evaluate.
I guess we can't do that without distinguishing numbers from numerals, etc.
and I guess none of us are ready to do anything that radical.
So as a compromise condition, I think we should limit the set of self-evaluating
data to not include things for which there is no re-readable print syntax. The
rationale would be that things which you can type in can reasonably be expected
to occur in programs and things which you cannot are likely to be errors. QUOTE,
of course, could be used to say "I really mean this". So strings, numbers, true,
false, etc. would therefore be self-evaluating. The empty list is arguably a
special case because its type is already defined to refer to combinations and
it is empty, so I think it should be an error and you should have to say '().
∂14-Feb-86 2300 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Which constants must be quoted?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 14 Feb 86 22:59:59 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 15 FEB 86 02:01:20 EST
Date: Sat, 15 Feb 1986 01:59 EST
Message-ID: <CPH.12183480979.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
To: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Cc: JAR@MC.LCS.MIT.EDU, kend%tekla.uucp@CSNET-RELAY.ARPA,
RRRS-AUTHORS@MC.LCS.MIT.EDU,
willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
Subject: Which constants must be quoted?
In-reply-to: Msg of 14 Feb 1986 19:37-EST from Kent M Pitman <KMP at SCRC-STONY-BROOK.ARPA>
I agree with you completely.
∂17-Feb-86 1648 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Jonathan Rees for editor
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 17 Feb 86 16:48:13 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 17 Feb 86 19:49:44 EST
Received: from tektronix by csnet-relay.csnet id bd01120; 17 Feb 86 19:02 EST
From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
To: RRRS-AUTHORS@mc.lcs.mit.edu
Cc: willc%tektronix.csnet@CSNET-RELAY.ARPA, JAR@mc.lcs.mit.edu
Received: from tekchips by tektronix with smtp ; 17 Feb 86 13:44:55 PST
Comment: Message received over unauthenticated port at tektronix
Received: by tekchips (5.31/5.14), id AA09024; Mon, 17 Feb 86 13:46:02 PST
Message-Id: <8602172146.AA09024@tekchips>
Subject: Jonathan Rees for editor
In-Reply-To: Your message of Thu, 13 Feb 86 15:58:41 EST., <[MC.LCS.MIT.EDU].817505.860213.JAR>
Date: 17 Feb 86 13:45:54 PST (Mon)
Jonathan Rees once volunteered to do the next edition of the RRRS, fixing
a number of minor problems such as the inconsistencies that have been
noted concerning constants. There's certainly no one I'd trust more
to do it, and so I move that we take him up on his offer.
Are you still willing, Jonathan?
----------------------------------------------------------------
By the way, I have a few remarks in response to Jonathan's observations
on quote. Jonathan's words are indented.
For example, suppose there's a bug in a macro, and it returns a closure
instead of a lambda-exparession....
I've been burned by that in MacScheme, where quotes are optional except
for symbols and non-empty lists.
So I think that an intermediate position between 2 and 3 *can* be
justified by the principle of Occam's razor, and we should disallow
self-evaluation of vectors, procedures, and other "random" objects
because it's unnecessary....
No, no. Self-evaluation of numbers and strings is also unnecessary, so
no intermediate position can be justified by Occam's razor or any other
principle. It is important that we acknowledge the lack of a principled
justification, because some of us can be stubborn and downright ornery
if we think we're arguing about principles rather than personal tastes.
It is true that distinctions become arbitrary here, but in each case we
can apply judgement the same way that we applied judgement in the
inclusion of any language feature....
Exactly right. I'd be happy with the judgment of the RRRS on this matter
if it were made internally consistent, and I think most others would also.
peace, Will
∂17-Feb-86 1946 JAR@MC.LCS.MIT.EDU quotation
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 17 Feb 86 19:45:51 PST
Date: Mon, 17 Feb 86 22:47:24 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: quotation
To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of 17 Feb 86 13:45:54 PST (Mon) from willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
Message-ID: <[MC.LCS.MIT.EDU].821043.860217.JAR>
Date: 17 Feb 86 13:45:54 PST (Mon)
From: willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
No, no. Self-evaluation of numbers and strings is also unnecessary, so
no intermediate position can be justified by Occam's razor or any other
principle. It is important that we acknowledge the lack of a principled
justification, because some of us can be stubborn and downright ornery
if we think we're arguing about principles rather than personal tastes.
OK, I freely admit it: I'm making arguments based not on principle but
on taste. And, as everyone knows by now, I am both ornery and stubborn,
no matter what I'm talking about.
The principled position which I would have liked to take, of making
NOTHING self-evaluate (except (let ((x '`(let ((x ',x)) ,x))) `(let ((x
',x)) ,x)) and things of that ilk), is out of the question, since it would
be a grossly incompatible change, besides being politically doomed.
It is true that distinctions become arbitrary here, but in each case we
can apply judgement the same way that we applied judgement in the
inclusion of any language feature....
Exactly right. I'd be happy with the judgment of the RRRS on this matter
if it were made internally consistent, and I think most others would also.
Maybe you misunderstood me; I meant to argue that each different
expression type (vector, character, etc.) should be considered on its
own merit, and that it didn't make much sense to come up with a general
rule to decide all such questions; they don't necessarily have anything
in common with each other. (The term "self-evaluation" is really
inappropriate to our description method anyhow, which takes pains to
distinguish objects from expressions.) But I won't press this point.
Apparently I need to find a way to construe my desire that numbers,
strings, and characters self-evaluate, and vectors and () not
self-evaluate, as being internally consistent. (I never wanted #!true
or #!false to self-evaluate, but won't fight a decision that's already
been made.) I think you're asking for an awful lot, certainly not
something that has been achieved elsewhere in the language design. But
before arguing further against your terms of argument (which I'll try
next if this attempt fails), let me hazard one more attempt at internal
consistency: "Atomic" objects (other than symbols) self-evaluate, and
"composite" objects don't. For present purposes "composite" objects
comprise vectors and lists, and lists include (). Since we haven't
established a meaning for vectors or (), they are not (yet)
syntactically valid expressions, much less self-evaluating ones.
"Random" objects don't much bear on this discussion because they don't
have external syntax, and the language has neither EVAL nor macros. But
if there were any way to evaluate or compile an unreadable object, I
think we all agree that the appearance of one within a program would be
an error.
∂19-Feb-86 1839 JAR@MC.LCS.MIT.EDU EQ?, again
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 19 Feb 86 18:37:34 PST
Date: Wed, 19 Feb 86 21:37:49 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: EQ?, again
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].823678.860219.JAR>
I hate to drag this out of the closet, but as I remember, there was no
agreement on the question of the semantics of EQ? and EQV?, and in fact
we seemed deadlocked. So I would like to take a survey. I think most
of us have pretty strong opinions, so I'm not sure how much good more
arguing will do right now, but I'm interested in finding out what
everyone thinks. I will be happy to collate and summarize the results
of the survey. You may send your answers either to RRRS-AUTHORS or just
to me.
I believe that we all agree on what EQ? and EQV? do when presented with
cons cells, vectors, symbols, booleans, null, and strings. I think we
also agree on what EQV? does when it's presented with exact numbers and
characters. I don't think we agree on what EQ? does with numbers and
characters, or what either procedure does with procedures. I won't even
ASK about ports and continuations; we can discuss that later.
If you can & care to summarize your opinion or motivation in two or
three short sentences, feel free, but I'd like to see how the survey
goes before we start flaming again. If you've forgotten the debate and
would like me to re-send any of the main position messages on this topic
(Pitman, Steele, and Clinger are the ones I remember) just ask and I'll
do so.
Here's the survey. If you object to it, please invent a better one.
-----
For each expression, specify what you think its value or meaning should
be, one of:
T - Always true
F - Always false
I - Implementation-dependent but NOT AN ERROR
E - An error (undefined effect)
X - I don't care
U - Undecided
O - Other (specify)
Here are the expressions:
1. (EQ? (LAMBDA (X) X) (LAMBDA (Y) Y)) ;"Coalescing"
2. (EQV? (LAMBDA (X) X) (LAMBDA (Y) Y))
3. (LET ((X (LAMBDA (Z) Z))) (EQ? X X)) ;"Splitting"
4. (LET ((X (LAMBDA (Z) Z))) (EQV? X X))
5. (LET ((X ... any expression evaluating to an exact number ...))
(EQ? X X))
6. (EQ? #\X #\X)
∂19-Feb-86 2209 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: quotation
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 19 Feb 86 22:08:59 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 20 Feb 86 01:08:54 EST
Received: from tektronix by csnet-relay.csnet id ab06340; 20 Feb 86 0:47 EST
From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
To: JAR@mc.lcs.mit.edu
Cc: willc%tektronix.csnet@CSNET-RELAY.ARPA, RRRS-AUTHORS@mc.lcs.mit.edu
Received: from tekchips by tektronix with smtp ; 19 Feb 86 10:05:12 PST
Comment: Message received over unauthenticated port at tektronix
Received: by tekchips (5.31/5.14), id AA24330; Wed, 19 Feb 86 10:06:16 PST
Message-Id: <8602191806.AA24330@tekchips>
Subject: Re: quotation
In-Reply-To: Your message of Mon, 17 Feb 86 22:47:24 EST., <[MC.LCS.MIT.EDU].821043.860217.JAR>
Date: 19 Feb 86 10:06:11 PST (Wed)
I know I'm stubborn and downright ornery, but I'm surprised to learn that
Jonathan is too. He's been fooling me all this time.
Exactly right. I'd be happy with the judgment of the RRRS on this
matter if it were made internally consistent, and I think most others
would also.
I think you're asking for an awful lot, certainly not something that
has been achieved elsewhere in the language design.
All I meant is that the wording in one part of the document should be
made consistent with the wording in other parts of the document.
Peace, Will
∂20-Feb-86 0713 @MC.LCS.MIT.EDU:KMP@SCRC-STONY-BROOK.ARPA EQ?, again
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 20 Feb 86 07:13:15 PST
Received: from SCRC-STONY-BROOK.ARPA by MC.LCS.MIT.EDU 20 Feb 86 10:13:36 EST
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 421054; Thu 20-Feb-86 09:58:05-EST
Date: Thu, 20 Feb 86 10:00 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: EQ?, again
To: JAR@MC.LCS.MIT.EDU
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-Reply-To: <[MC.LCS.MIT.EDU].823678.860219.JAR>
Message-ID: <860220100001.2.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Executive Summary: 1-O, 2-O, 3-U, 4-U, 5-T, 6-T
1. (EQ? (LAMBDA (X) X) (LAMBDA (Y) Y)) ;"Coalescing"
O. Mathematically equivalent functions should be allowed to return
true, but not required to EXCEPT when the implementation provides
any operation which could distinguish the resulting objects using
non-functional means. That is, if an operation
(DISCLOSE (LAMBDA (X) X)) returns (LAMBDA (X) X)
then (EQ? X Y) would not be allowed return true for mathematically
equivalent functions unless (EQ? (DISCLOSE X) (DISCLOSE Y)) would
also return true, and so on. In the special case where such
operations were provided and the compiler could prove that they
would never be used, I have no objection to optimizing the two
closures to be eq. That is,
(DEFINE FOO (LAMBDA (X) X))
(DEFINE BAR (LAMBDA (Y) Y))
(EQ? FOO BAR)
should be required to return false in implementations which support
debugging operations that could distinguish FOO and BAR, but
(EQ? (LAMBDA (X) X) (LAMBDA (Y) Y))
in the same implementation should be permitted to return true. My
point being that EQ? is currently an essential primitive in system
design and it would be a shame to let it get turned into something
which thwarted debugging.
2. (EQV? (LAMBDA (X) X) (LAMBDA (Y) Y))
O. I think it important to say that EQV? cannot return false when EQ?
has returned true. The combination of this point and my arguments
in 1 above lead to the conclusion that this may return true sometimes
but may not (for reasons related to halting problems) not be required
to do so.
3. (LET ((X (LAMBDA (Z) Z))) (EQ? X X)) ;"Splitting"
U. My intuition says that this should always return true, but Jonathan
has convinced me to think harder on the issue before insisting that
the intuition is valid. I would like to reserve the right to speak
later on this one.
4. (LET ((X (LAMBDA (Z) Z))) (EQV? X X))
U. My intuition is also that this should return true, but I am not
currently taking a stand pending a resolution on item 3.
5. (LET ((X ... any expression evaluating to an exact number ...))
(EQ? X X))
T. I believe my views on this are on record already.
6. (EQ? #\X #\X)
T. If there is some argument from Will or Jonathan as to why this
would clutter the semantics, I don't think I've heard it. Depending
on my decision about item 3, I may be willing to change my views
on this if I heard a argument for it.
∂20-Feb-86 1147 JAR@MC.LCS.MIT.EDU EQV? note
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 20 Feb 86 11:36:31 PST
Date: Thu, 20 Feb 86 14:36:55 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: EQV? note
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].824527.860220.JAR>
Let me repeat for about the third time my request that EQV? have
machine-independent semantics. I believe that this is a logical
consequence of the intended "spirit" of EQV? which (I thought) is that
it be a *clean* fine-grained equality predicate. I feel a little
insulted that people haven't even taken this suggestion seriously enough
to argue against it. Judging form the number of "I" answers to the
survey's EQV? questions, most people seem to disagree with this,
although they won't say why. I'll assume people have just forgotten
that I suggested this, but I would like some reaction.
∂20-Feb-86 1157 JAR@MC.LCS.MIT.EDU survey - JAR's answers
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 20 Feb 86 11:47:46 PST
Date: Thu, 20 Feb 86 14:48:08 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: survey - JAR's answers
To: JAR@MC.LCS.MIT.EDU
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Wed 19 Feb 86 21:37:49 EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
Message-ID: <[MC.LCS.MIT.EDU].824547.860220.JAR>
Here are my own answers.
I 1. (EQ? (LAMBDA (X) X) (LAMBDA (Y) Y)) ;"Coalescing"
E 2. (EQV? (LAMBDA (X) X) (LAMBDA (Y) Y))
I 3. (LET ((X (LAMBDA (Z) Z))) (EQ? X X)) ;"Splitting"
E 4. (LET ((X (LAMBDA (Z) Z))) (EQV? X X))
I 5. (LET ((X ... exact number ...)) (EQ? X X))
X 6. (EQ? #\X #\X)
These are the only possible choices given the conjunction of the
following constraints, which I find desirable:
(a) I want to give implementations a lot of leeway in the optimizations they
do on closures.
(b) I want closures to not have associated locations (in the sense of
denotational semantics), i.e. I want to equate a closure with its behavior
when called.
(c) I want EQV? to behave in a machine-independent manner, without requiring
that it solve the halting problem.
Jonathan.
∂20-Feb-86 1157 JAR@MC.LCS.MIT.EDU EQV? note (tiny correction)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 20 Feb 86 11:56:58 PST
Date: Thu, 20 Feb 86 14:57:27 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: EQV? note (tiny correction)
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Thu 20 Feb 86 14:36:55 EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
Message-ID: <[MC.LCS.MIT.EDU].824565.860220.JAR>
I meant to say "implementation-independent," not "machine-independent."
∂20-Feb-86 1450 JAR@MC.LCS.MIT.EDU further clarification
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 20 Feb 86 14:50:02 PST
Date: Thu, 20 Feb 86 17:50:28 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: further clarification
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].824794.860220.JAR>
On talking with Bill Rozas about EQV?, I think I should clarify my
position, in order to help people understand it. I haven't been very
clear.
Suppose that X and Y are expressions which evaluate to procedures or
numbers. Then I want the following two rules to hold.
(A) If (EQ? X Y) returns true, then the values of X and Y have the same
meaning with respect to all operations, including
implementation-dependent ones. (Note that the converse is not
true. I think we all agree about this rule.)
(B) If (EQV? X Y) is defined, then it should return true or false
depending on whether or not the values of X and Y have the same
meaning with respect to all implementation-independent Scheme
operations. If not, then implementations may choose to take any
action appropriate to situations that "are errors": return true,
false, or some other value, or signal an error, or do something
else. (So far everyone has disagreed with me about this.)
Thus (EQ? X Y) implies (EQV? X Y) whenever (EQV? X Y) is defined.
Also, since the only thing you can do with a procedure is call it, then
EQV? on two procedures would have to determine whether two procedures do
the same thing, which is in general impossible. So in order for rule
(B) to hold, if X and Y are both procedures, then (EQV? X Y) must be
undefined.
I want to be able to use EQ? to do things like caching (memoization);
some implementations may choose to invariably return false when given
two procedures, but if they return true sometimes (subject to rule A)
then my programs might run faster. If I want to convince myself that my
program which uses EQ? is portable, I may have to do some rather
sophisticated reasoning, allowing for the fact that results may be
indeterminate.
On the other hand, I want to know that if my program which uses EQV?
never passes two procedures to EQV?, and is otherwise in no way
implementation-sensitive, then I can have complete confidence that it
will run the same way in any correct Scheme implementation. In
particular, if I convince myself that the program works in my
implementation (by testing it or using any other technique), then I will
have no trouble convincing myself that it will work when run by any
other implementation.
The set of implementation-independent primitives is already pretty
large, and I want to include EQV? in that set, to permit very naive
portability criteria (like "EQ? doesn't occur").
I DON'T want programs which use EQV? to gratuitously work just because I
happen to be using some particular implementation. I might fool myself
into thinking the program will work in others. So I want to allow my
implementation to signal an error.
[I guess my criterion (B) is pretty strong. I hope that this doesn't
precipitate a discussion of the meaning of QUOTE. Please don't even
think about mentioning that, before we get this issue straightened out.]
Sorry to be long-winded. Please either shoot me down or bear with.
Jonathan.
∂20-Feb-86 1737 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA publication of RRRS in SIGPLAN Notices
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 20 Feb 86 17:37:03 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 20 Feb 86 20:06:24 EST
Received: from tektronix by csnet-relay.csnet id ac16010; 20 Feb 86 18:48 EST
From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
To: RRRS-AUTHORS@mc.lcs.mit.edu
Received: from tekchips by tektronix with smtp ; 20 Feb 86 10:34:52 PST
Comment: Message received over unauthenticated port at tektronix
Received: by tekchips (5.31/5.14), id AA08527; Thu, 20 Feb 86 10:36:12 PST
Message-Id: <8602201836.AA08527@tekchips>
Subject: publication of RRRS in SIGPLAN Notices
Date: 20 Feb 86 10:36:07 PST (Thu)
Last month, at the ACM POPL conference, representatives of ACM SIGPLAN
requested that we submit the RRRS for publication in ACM SIGPLAN Notices.
This would make the RRRS available to a much wider audience, give it
more influence, and would satisfy editors who dislike citations of technical
reports. ACM SIGPLAN has begun a policy of publishing programming language
manuals for interesting new languages, and recent issues of SIGPLAN Notices
have contained definitions of Poly, Modcap, and B, among others.
Jonathan Rees has agreed to fix up a few minor bugs in the RRRS and to
reformat it for more compact publication. If no one objects, he will
submit the result to SIGPLAN Notices in a few weeks.
People haven't been flaming me for errors in RRRS, so I've asked Jonathan
not to list me as editor.
Is this ok with everybody?
Peace, Will Clinger
willc%tekchips@tektronix.csnet
∂21-Feb-86 0529 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA proposing changes to RRRS
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 21 Feb 86 05:29:07 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 21 Feb 86 08:29:30 EST
Received: from tektronix by csnet-relay.csnet id aa03527; 21 Feb 86 8:01 EST
From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
To: RRRS-AUTHORS@mc.lcs.mit.edu
Received: from tekchips by tektronix with smtp ; 20 Feb 86 16:57:39 PST
Comment: Message received over unauthenticated port at tektronix
Received: by tekchips (5.31/5.14), id AA05866; Thu, 20 Feb 86 16:59:00 PST
Message-Id: <8602210059.AA05866@tekchips>
Subject: proposing changes to RRRS
Date: 20 Feb 86 16:58:57 PST (Thu)
Here is a list of changes I (Will Clinger) would like to see made in the
RRRS. Only three changes have enough substance to be controversial.
Page numbers refer to MIT AI Memo 848, August 1985.
Non-controversial changes
----------------------------------------------------------------
Pages 7, 12, 48, and 54: The context free grammar omits characters and
vectors as constants, and is therefore inconsistent with the language
describing the quote special form and the notations for characters and
vectors. This should be fixed. Note, however, that the # notations
for characters and vectors are optional.
----------------------------------------------------------------
Page 7: Backquote doesn't fit into the context free grammar. A correct
treatment of backquote syntax may be more trouble than it's worth in an
informal document, however.
----------------------------------------------------------------
Page 7: Variables are referred to as objects, but they're not.
----------------------------------------------------------------
Page 22: It says that "pairs (and therefore lists)" count as true.
It should say "pairs (and therefore nonempty lists)", or else just "pairs".
----------------------------------------------------------------
Page 25: eqv? should work on characters also.
----------------------------------------------------------------
Page 30: People have requested that the last argument to append
not be required to be a proper list.
----------------------------------------------------------------
Page 43: The grammar is ambiguous as to whether (for example) #x1e4
represents decimal 10000 or decimal 484. Following Common Lisp, let's
say that "interpretation as a digit is preferred to interpretation as"
an exponent.
----------------------------------------------------------------
Page 43: There are no rules about the exactness or precision to be
used on input if none is specified. I think that's just fine until
we get more experience with the RRRS number system, but a sentence
to that effect would be helpful.
----------------------------------------------------------------
Page 49: The character set should not have to be infinite, so the
order isomorphisms should be between the set of characters and a
*subset* of the integers.
----------------------------------------------------------------
Controversial changes
----------------------------------------------------------------
Page 17: I'd still like to see named-lambda removed from the language
definition. Any implementation capable of handling
(named-lambda (var ...) ...) specially should be capable of handling
(rec var (lambda (...) ...)) specially.
----------------------------------------------------------------
Page 19: In talking about do, RRRS says that "the results of the step
expressions are stored in the bindings of the vars". I would rather change
the semantics so that the step expressions are evaluated, the vars are
bound to fresh locations, and the results of the step expressions are
stored into those locations.
The current semantics is compatible with Common Lisp, but the proposed
semantics is better not only because it has no side effects but also because
it is likely to run faster when compiled by a sophisticated compiler. I
don't think many people will notice the difference, and the few who are
sophisticated enough to notice will probably prefer the proposed semantics.
The proposed semantics is the one that has been used in Scheme up until
the RRRS. MacScheme and T3 still use it in violation of RRRS; others
may also. The change was due to my thoughtless acceptance of the Common
Lisp semantics.
----------------------------------------------------------------
Pages 24-25: We have agreed that eq? is a low-level notion of object
identity. I would like to adopt Jonathan's proposal that eqv? be
defined independently of eq?. I believe the main effect of this is
that the result of eqv? when given procedures as arguments would
not be specified.
∂21-Feb-86 1337 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU proposing changes to RRRS
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 21 Feb 86 13:27:22 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 21 FEB 86 16:13:11 EST
Date: Fri, 21 Feb 1986 15:16 EST
Message-ID: <CPH.12185198902.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: proposing changes to RRRS
In-reply-to: Msg of 20 Feb 1986 19:58-EST from willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
Date: Thursday, 20 February 1986 19:58-EST
From: willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
Controversial changes
----------------------------------------------------------------
Page 17: I'd still like to see named-lambda removed from the language
definition. Any implementation capable of handling
(named-lambda (var ...) ...) specially should be capable of handling
(rec var (lambda (...) ...)) specially.
I agree, despite the fact that I invented this one in MIT Scheme (I
wish I hadn't, this special form proliferation is driving me nuts!) I
would go one step farther, in proposing to flush REC as well, since
such an implementation could also handle the special case of LETREC
just as easily (however, I bet there are folks out there, unlike me,
who use REC all the time.)
----------------------------------------------------------------
Page 19: In talking about do, RRRS says that "the results of the step
expressions are stored in the bindings of the vars". I would rather change
the semantics so that the step expressions are evaluated, the vars are
bound to fresh locations, and the results of the step expressions are
stored into those locations.
The proposed semantics is the one that has been used in Scheme up until
the RRRS. MacScheme and T3 still use it in violation of RRRS; others
may also.
Yes! I never even looked at it closely enough to notice that the MIT
Scheme implementation also uses the proposed semantics rather than the
RRRS semantics.
∂21-Feb-86 1407 JAR@MC.LCS.MIT.EDU proposing changes to RRRS
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 21 Feb 86 14:02:22 PST
Date: Fri, 21 Feb 86 17:02:55 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: proposing changes to RRRS
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of 20 Feb 86 16:58:57 PST (Thu) from willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
Message-ID: <[MC.LCS.MIT.EDU].826238.860221.JAR>
Date: 20 Feb 86 16:58:57 PST (Thu)
From: willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
Non-controversial changes
We seem to have opposing ideas of what's controversial and what's
non-controversial. Hate to spoil the harmony with my remarks, but I
feel compelled. I don't want to be embarrassed to have this thing
appear in SIGPLAN. (Will that remark help convince people that I'm
ornery?)
----------------------------------------------------------------
Pages 7, 12, 48, and 54: The context free grammar omits characters and
vectors as constants, and is therefore inconsistent with the language
describing the quote special form and the notations for characters and
vectors. This should be fixed. Note, however, that the # notations
for characters and vectors are optional.
I think this depends on the outcome of the debate on self-evaluation of
characters and vectors, which may overturn what page 12 says. E.g. if
vectors aren't going to be self-evaluating, then they probably needn't
be mentioned on page 7, since they won't belong to the language
<expression> but rather to the language <datum>, and it is stated that
the syntax of <datum> is spread throughout the manual. (My perception
is that consensus will be for characters to self-evaluate and vectors
not.) But regardless of how this comes out, I have a suggestion to
make: on page 7, add the following explicit grammar for <datum>:
<datum> ::= <identifier> | <numeral> | <string> | #!true | #!false |
<character> | <list> | <vector>
Then mention that the syntax of <numeral>, <list>, etc. is found
elsewhere, and maybe give page numbers. Add a grammar for <list> on
page 26 which includes #!null, '<datum>, and `<pattern> (or `<datum>,
,<datum>, and ,@<datum>, see below). Add the obvious grammar for
<vector> on page 54, for completeness.
I think that the description of READ should mention that what it does is
recognize the <datum> nonterminal, and return an object which represents
the parse tree in a natural way (the same way as QUOTE). Also, if we
can get the backquote problem ironed out, a statement should be made
somewhere to the effect that the language <expression> is a (strict)
subset of the language <datum> and that this while to the uninitiated
this might appear to be a confusing coincidence, actually the
uninitiated are right.
Controversial changes [flush named-lambda, change do, change eq? and eqv?]
I agree with all of these changes.
Please note that in debating the EQ? and EQV? changes, the two
questions, essentially (a) should eqv? be implementation-dependent and
(b) should procedures and numbers have associated locations, can and
probably should be treated independently.
∂21-Feb-86 2249 @MC.LCS.MIT.EDU:OXLEY%%ti-csl.csnet@CSNET-RELAY.ARPA Who Is Using Scheme? For What?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 21 Feb 86 22:49:12 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 22 Feb 86 01:45:39 EST
Received: from ti-csl by csnet-relay.csnet id ak04008; 22 Feb 86 1:43 EST
Received: by tilde id AA07158; Thu, 20 Feb 86 16:26:20 cst
Date: Thu 20 Feb 86 16:04:10-CST
From: Don Oxley <OXLEY%%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Who Is Using Scheme? For What?
To: Scheme%MIT-MC%csnet-relay@CSNET-RELAY.ARPA
Message-Id: <12184956321.17.OXLEY@CSL60>
Over the few weeks since PC Scheme has become available, I have had a
number of questions about who is using Scheme, what they are doing,
etc. There seems to be a number of persons/groups who are undertaking
interesting projects and or courses involving Scheme (PCS or
otherwise) but there is very little evidence of communication among
the users themselves. (There is getting to be a moderate volume of
communication between users and many of us here at TI.)
We at TI would like to encourage the development of an active
community which is discussing Scheme and its use, sharing ideas and
code, etc. The existing SCHEME mailing list at MIT seems to be the
appropriate forum for discussion if we can convince people to sign up
and/or exploit it. In particular, we at TI would like to assist and
participate in the process, but would NOT like to become any focal
point or filter because of our proprietary interests.
I encourage you to do two things:
(1) Reply to this message (to SCHEME@MIT-MC, not to me) with a brief
summary of how/why... you are using Scheme along with any particulars
you can supply (eg., dialect, status of effort...). If you have
particularly interesting code or code segments, problem sets,
instructional materials, ... which you would be willing to share
please describe them. If there are issues or topics on which you
would like to see a discussion, please include them as well.
(2) If you know of other Scheme users who may not see this message,
forward it to them and ask them to get on the list. This can be done
by sending mail to Scheme-Request@MIT-MC and asking to be included on
SCHEME@MIT-MC.
I am particularly interested in the experiences of our new PC Scheme
users. I hope to use the feedback to further the cause of Scheme here
at TI and to help us improve the product itself. I'm sure the other
system developers will welcome such feedback also.
Thanks,
--Don Oxley
-------
∂21-Feb-86 2345 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA EQ? Survey Entry
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 21 Feb 86 23:45:18 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 22 Feb 86 02:45:53 EST
Received: from ti-csl by csnet-relay.csnet id ah04008; 22 Feb 86 1:40 EST
Received: by tilde id AA00860; Thu, 20 Feb 86 10:15:10 cst
Date: Thu 20 Feb 86 10:10:56-CST
From: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: EQ? Survey Entry
To: RRRS-AUTHORS%MIT-MC%csnet-relay@CSNET-RELAY.ARPA
Cc: Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
Message-Id: <12184892016.40.BARTLEY@CSL60>
1. (EQ? (LAMBDA (X) X) (LAMBDA (Y) Y)) ;"Coalescing" ==> I
2. (EQV? (LAMBDA (X) X) (LAMBDA (Y) Y)) ==> I
3. (LET ((X (LAMBDA (Z) Z))) (EQ? X X)) ;"Splitting" ==> I
4. (LET ((X (LAMBDA (Z) Z))) (EQV? X X)) ==> I
5. (LET ((X ... any expression evaluating to an exact number ...)) ==> I
(EQ? X X))
6. (EQ? #\X #\X) ==> I
My position is quite simple: EQ (EQ?) has historically been
implementation-dependent and is the wrong function to be associated
with any kind of formal ``identity'' predicate. Let's define EQ? to
be a predicate on representations, not abstract types, and let's
decide which representational identities we're going to require of a
conforming implementation.
The reason I want such an EQ? is two-fold: (1) We need an identity
predicate for symbols, and (2) we need to know when we have the same
*instance* of a mutable object so we know which one we are modifying.
Thus, I suggest that EQ? be defined only for symbols, booleans, (),
and mutable objects (pairs, vectors, strings, and ports). It should
be undefined (implementation-dependent but not an error) for numbers,
characters, closures, and continuations.
Thus (EQ? X X) is not necessarily #!TRUE unless X is appropriately
typed. I believe this position is consistent with Will's.
I agree with Jonathan that EQV? should also be defined over an
incomplete domain. I'd like to see it extend EQ? to encompass exact
numbers and characters but not closures and continuations.
EQUAL? should be like EQV?, but also knows how to descend into
subcomponents of pairs and vectors. Again, it should not be defined
for closures and continuations.
Perhaps we should define an EQL? if someone really wants a predicate
that somehow tries to do the ``right thing'' for closures and
continuations, but I don't have any need for it.
Regards,
David Bartley
-------
∂22-Feb-86 0547 @MC.LCS.MIT.EDU:adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: survey - JAR's answers
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 22 Feb 86 05:47:02 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 22 Feb 86 06:22:52 EST
Received: from tektronix by csnet-relay.csnet id av05897; 22 Feb 86 6:12 EST
From: adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
To: JAR@mc.lcs.mit.edu
Cc: RRRS-AUTHORS@mc.lcs.mit.edu
Received: from tekchips by tektronix with smtp ; 21 Feb 86 16:00:22 PST
Comment: Message received over unauthenticated port at tektronix
Received: by tekchips (5.31/5.14), id AA24786; Fri, 21 Feb 86 16:01:47 PST
Message-Id: <8602220001.AA24786@tekchips>
Subject: Re: survey - JAR's answers
Date: 21 Feb 86 16:01:41 PST (Fri)
I 1. (EQ? (LAMBDA (X) X) (LAMBDA (Y) Y)) ;"Coalescing"
E 2. (EQV? (LAMBDA (X) X) (LAMBDA (Y) Y))
I 3. (LET ((X (LAMBDA (Z) Z))) (EQ? X X)) ;"Splitting"
E 4. (LET ((X (LAMBDA (Z) Z))) (EQV? X X))
U 5. (LET ((X ... exact number ...)) (EQ? X X))
X 6. (EQ? #\X #\X)
I agree with your answers and reasons on 1-4.
5. As I understand it, specifying that this expression returns true might
preempt certain optimizations in numerical code. (Like not consing
intermediate results by using unboxed number representations that are not
available to the user.) I would agree with Jonathan (with an 'I'), but I don't
feel too strongly about it, so I could be swayed.
6. This seems the same as 5, except that characters are less likely
candidates for optimizations. Since it doesn't affect the compiler,
and its easy to implement either (any) way, I don't care.
-Norman
∂22-Feb-86 0550 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: EQ?, again
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 22 Feb 86 05:50:01 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 22 Feb 86 06:26:17 EST
Received: from tektronix by csnet-relay.csnet id ak05897; 22 Feb 86 6:07 EST
From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
To: JAR@mc.lcs.mit.edu
Cc: RRRS-AUTHORS@mc.lcs.mit.edu
Received: from tekchips by tektronix with smtp ; 21 Feb 86 11:11:17 PST
Comment: Message received over unauthenticated port at tektronix
Received: by tekchips (5.31/5.14), id AA19306; Fri, 21 Feb 86 11:12:33 PST
Message-Id: <8602211912.AA19306@tekchips>
Subject: Re: EQ?, again
In-Reply-To: Your message of Wed, 19 Feb 86 21:37:49 EST., <[MC.LCS.MIT.EDU].823678.860219.JAR>
Date: 21 Feb 86 11:12:30 PST (Fri)
Executive summary: 1-I 2-E 3-I 4-E 5-I 6-X
(i.e., the straight Jonathan party ticket)
I 1. (EQ? (LAMBDA (X) X) (LAMBDA (Y) Y)) ;"Coalescing"
E 2. (EQV? (LAMBDA (X) X) (LAMBDA (Y) Y))
I 3. (LET ((X (LAMBDA (Z) Z))) (EQ? X X)) ;"Splitting"
E 4. (LET ((X (LAMBDA (Z) Z))) (EQV? X X))
I 5. (LET ((X ... any expression evaluating to an exact number ...))
(EQ? X X))
X 6. (EQ? #\X #\X)
Notes:
Re example 2, Kent Pitman writes:
I think it important to say that EQV? cannot return false when EQ?
has returned true.
This would make EQV? implementation-dependent, just like EQ?. If EQV?
of two procedures is an error, however, then it would be fair to have an
implementation note suggesting that if EQV? does not actually report
an error when applied to procedures, it should return whatever EQ? returns.
Such a note would not be part of the semantics of EQV?, because there is no
way anyone could rely on it to write implementation-independent code.
Re example 5, I nearly said I didn't care. The main reason I care is that
I think a T vote for example 5 should imply a T vote for
(LET ((X ... any expression evaluating to an exact number ...))
(EQ? X (1+ (-1+ X))))
and I suspect that people who vote T on example 5 won't agree.
Peace, Will
∂22-Feb-86 1517 @MC.LCS.MIT.EDU:fickas%uo-vax1%uoregon.csnet@CSNET-RELAY.ARPA Use of MacScheme
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 22 Feb 86 15:17:20 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 22 Feb 86 15:33:37 EST
Received: from uoregon by csnet-relay.csnet id a009777; 22 Feb 86 15:31 EST
Received: from uo-vax1.UONET (uo-vax1) by uo-vax3.UONET with TCP (4.12/1.0.UofO)
id AA01281; Sat, 22 Feb 86 11:49:53 pst
Received: by uo-vax1.UONET (4.12/1.0.UofO)
id AA21105; Sat, 22 Feb 86 11:46:26 pst
Date: Sat, 22 Feb 86 11:46:26 pst
From: Steve Fickas <fickas%uo-vax1%uoregon.csnet@CSNET-RELAY.ARPA>
Posted-Date: Sat, 22 Feb 86 11:46:26 pst
Message-Id: <8602221946.AA21105@uo-vax1.UONET>
To: scheme@mc.lcs.mit.edu
Subject: Use of MacScheme
Cc: fickas%uo-vax1%uoregon.csnet@CSNET-RELAY.ARPA,
art%uo-vax2%uoregon.csnet@CSNET-RELAY.ARPA
In answer to Don Oxley's call for information, we are just concluding
an experimental Scheme section of our intro course for CS majors. We used
MacScheme on the Macintosh (from Semantic Microsystems) and Abelson and
Sussman's book over two quarters. We judged the experiment to have been a
qualified success, and at this point plan to use Scheme (along with Modula-2)
for all sections next year.
We have built a moderate amount of instructional software in support
of the course; we would be glad to share it, although most of it relies
on the Mac's toolbox. We'd also be happy to discuss problems we ran
into, what will change next year, etc.
Steve Fickas and Art Farley
Computer Science Department
University of Oregon
Eugene, Or. 97403
(503) 686-4408
fickas@uoregon, art@uoregon
∂23-Feb-86 1454 @MC.LCS.MIT.EDU:skrzypek@LOCUS.UCLA.EDU SCHEME based PC Vision Station
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 23 Feb 86 14:54:40 PST
Received: from LOCUS.UCLA.EDU by MC.LCS.MIT.EDU 23 Feb 86 17:54:05 EST
Date: Sun, 23 Feb 86 14:33:32 PST
From: "Dr. Josef Skrzypek" <skrzypek@LOCUS.UCLA.EDU>
To: SCHEME@MIT-MC
Subject: SCHEME based PC Vision Station
Message-ID: <509582012-13086-skrzypek@DIANA.LOCUS.UCLA.EDU>
PCVS Project
Scheme-based Personal Computer Vision Station is being developed
by a group my graduate students in Computer Science Dept. We are
using version 1.0 for software and Imaging Technology board FG100AT
as a front-end hardware for image acquisition. The PCVS will be
used for instructional purposes in the undergraduate and graduate
courses on Computer Vision.
--josef skrzypek
∂24-Feb-86 0816 @MC.LCS.MIT.EDU:Swenson.Multics@CISL-SERVICE-MULTICS.ARPA Re: Who Is Using Scheme? For What?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 24 Feb 86 08:16:50 PST
Received: from CISL-SERVICE-MULTICS.ARPA by MC.LCS.MIT.EDU 24 Feb 86 11:15:45 EST
Posted-Date: 24 Feb 86 11:10 EST
Acknowledge-To: "Eric J. Swenson" <Swenson@CISL-SERVICE-MULTICS.ARPA>
Date: Mon, 24 Feb 86 11:08 EST
From: "Eric J. Swenson" <Swenson@CISL-SERVICE-MULTICS.ARPA>
Subject: Re: Who Is Using Scheme? For What?
To: Don Oxley <OXLEY%%ti-csl.csnet@CSNET-RELAY.ARPA>,
SCHEME@MC.LCS.MIT.EDU
In-Reply-To: Message of 20 Feb 86 17:04 EST from "Don Oxley"
Message-ID: <860224160818.006238@CISL-SERVICE-MULTICS.ARPA>
This is a reply to your query about SCHEME users:
I am taking a graduate course at Boston University entitled "Data
Abstractions and Object-Oriented Programming" in which SCHEME is the
primary language being used as a vehicle to discuss these topics.
Our instructor has several copies of the TI PC-SCHEME and is offering
student prices for the PC-SCHEME from TI to those students with IBM-PCs.
We also use a version of SCHEME for the VAX.
I am on the SCHEME mailing list, but I'm not sure if the professor is.
His name is Peter Mager and his Internet address is:
met128%bostonu.bitnet -at csnet-relay.arpa
Question: Does the TI PC-SCHEME work on Zenith Z-100s running MSDOS
version 2?
∂24-Feb-86 0842 NET-ORIGIN@MC.LCS.MIT.EDU EQ?, again
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 24 Feb 86 08:42:46 PST
Received: from ZERMATT.LCS.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 24 FEB 86 11:43:11 EST
Received: from ASPEN.LCS.MIT.EDU by MIT-ZERMATT.ARPA via CHAOS with CHAOS-MAIL id 25392; Mon 24-Feb-86 11:43:40-EST
Date: Mon, 24 Feb 86 11:43 EST
From: Robert Halstead <rhh@MIT-VAX.ARPA>
Subject: EQ?, again
To: JAR@MIT-MC.ARPA
cc: RRRS-AUTHORS@MIT-MC.ARPA
In-Reply-To: <[MC.LCS.MIT.EDU].823678.860219.JAR>
Message-ID: <860224114336.2.RHH@ASPEN.LCS.MIT.EDU>
Something that has not been mentioned in the debate over EQ? and EQV? as
applied to procedures is that one can use procedures as data
abstractions, including mutable data abstractions. Thus if it's useful
to be able to distinguish two cons cells or vectors using EQ? and/or
EQV?, so that one can determine whether the effects of an operation on
one will necessarily be visible in the other, then why isn't it equally
reasonable to use EQ? and/or EQV? to distinguish items returned by the
following procedure?
(define (procedural-cons a b)
(define (the-cons op . rest)
(cond ((eq? op 'car) a)
((eq? op 'cdr) b)
((eq? op 'set-car!)
(set! a (car rest))
the-cons)
...))
the-cons)
Stating that it is an error or implementation-dependent to use EQ? and
EQV? on such procedures will complicate using procedures to do
object-oriented programming where you want to be able to check the
identity of objects (it doesn't rule it out altogether because you could
still wrap the procedure representing the real object in a cons cell
whose purpose was to satisfy identity checks!). Are the kinds of
optimizations we want to do on procedures really important enough to
warrant throwing away this convenience? Alternatively, would specifying
a tighter semantics for EQ? and EQV? make the optimizations effectively
impossible, or would it just require a little more data flow analysis
during compilation to determine that the procedures in question would
never find their way to be operands of EQ? Perhaps somebody who has
thought about such optimizations and the kinds of programs in which we
would like to make them could comment.
In the absence of such input, I think my answers to questions 1-4 are
therefore
F 1. (EQ? (LAMBDA (X) X) (LAMBDA (Y) Y)) ;"Coalescing"
F 2. (EQV? (LAMBDA (X) X) (LAMBDA (Y) Y))
T 3. (LET ((X (LAMBDA (Z) Z))) (EQ? X X)) ;"Splitting"
T 4. (LET ((X (LAMBDA (Z) Z))) (EQV? X X))
Questions 5 and 6 get to the question of whether certain immutable data
types, notably numbers and characters, are subject to splitting when
viewed by EQ? or not. I am coming around to the viewpoint expressed by
others that the distinction between EQ? and EQV? is a historical
artifact that should probably be removed. The major expense associated
with that would be that, in most implementations, EQ? could no longer be
a simple pointer comparison, but would now have to investigate the type
of the objects being compared. Thus I can see the argument for keeping
EQ? for those cases where especially efficient execution is desired and
the programmer knows that none of the data types that can "split" when
viewed by EQ? are involved. But the price of this is the kind of
proliferation of other functions exemplified by the MEMQ/MEMV/MEMBER
family, which I think is unfortunate. Anyhow, I think my first vote
would be to flush EQ? and just keep EQV? (or else rename EQV? to EQ?).
But if we keep EQ? as a separate function, then in line with the
rationale expressed above, I think it should be an error to use EQ? on
things that may appear to split when viewed by EQ?. Therefore:
E 5. (LET ((X ... any expression evaluating to an exact number ...))
(EQ? X X))
For (6) the question is whether we want to require all implementations
to treat characters in a way that is never subject to splitting. I
don't really care much about this, though it seems that keeping
characters from splitting probably isn't too hard. Therefore:
X 6. (EQ? #\X #\X)
where the X really represents either E or T.
I realize that my answers regarding EQ? on functions may make it
substantially more difficult to do obvious, simple optimizations that
avoid consing up a closure when, e.g., a function with no free variables
appears inside another function. If this is too distasteful, perhaps we
should think about having two flavors of LAMBDA: ordinary
lambda-expressions such as (LAMBDA (X) X) would produce values which
would be an error to feed to EQ? or EQV?, but (CONSED-LAMBDA (X) X)
would produce values whose behavior under EQ? and EQV? would be
dependable. I'm not exactly wild about this idea, but it might offer a
way out and I thought I'd pass it along. I think I prefer it to the EQ?
alternatives that have been more frequently suggested in response to
JAR's survey.
Regarding NAMED-LAMBDA, I too would be happy to flush it in favor of the
REC or LETREC forms. -Bert
∂24-Feb-86 0922 @MC.LCS.MIT.EDU:allen@BBNJ.ARPA Butterfly Lisp
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 24 Feb 86 09:22:51 PST
Received: from BBNJ.ARPA by MC.LCS.MIT.EDU 24 Feb 86 12:04:55 EST
To: scheme@mit-mc.ARPA
cc: allen@BBNJ.ARPA
Subject: Butterfly Lisp
Date: 24 Feb 86 09:50:24 EST (Mon)
From: allen@BBNJ.ARPA
At BBN, we are basing our implementation of a Lisp for the Butterfly
multiprocessor on MIT's implementation of Scheme. Although ultimately
the surface language the users of our system will see will be Common Lisp,
we chose Scheme in part because of its relative simplicity and conceptual
cleanliness, making it a good setting for working out parallel processing
issues.
/Don Allen
∂24-Feb-86 0953 @MC.LCS.MIT.EDU:OXLEY%ti-csl.csnet@CSNET-RELAY.ARPA Re: Who Is Using Scheme? For What?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 24 Feb 86 09:53:32 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 24 Feb 86 12:44:38 EST
Received: from ti-csl by csnet-relay.csnet id ab27770; 24 Feb 86 12:37 EST
Received: by tilde id AA06119; Mon, 24 Feb 86 10:20:16 cst
Date: Mon 24 Feb 86 10:08:44-CST
From: Don Oxley <OXLEY%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Re: Who Is Using Scheme? For What?
To: OXLEY%%ti-csl.csnet@CSNET-RELAY.ARPA,
Scheme%MIT-MC <@CSNET-RELAY.ARPA:Scheme%MIT-MC@mit-mc%csnet-relay>
In-Reply-To: <12184956321.17.OXLEY@CSL60>
Message-Id: <12185940193.17.OXLEY@CSL60>
In replying to my own request for uses of Scheme:
We at TI are using Scheme (primarily PCS) in a number of different
projects - both in support of our research and for personal projects. I
am hopeful that others will reply in more detail on some of the
individual projects.
In addition to our interest in PCS as a product, TI has announced new
versions of our Personal Consultant and Arborist software packages which
are written in Scheme (support for these packages was one of the primary
reasons that PCS was created).
In our research efforts within my branch, we are using Scheme as a
systems programming language. We have developed packages for the PC
which allow us to control a TI Explorer as a microengine for
architectural research (the package is somewhat specific to our
particular needs, it is not a truly general facility). We are also
using Scheme (and PCS) as an implementation vehicle for our continuing
research in compilation techniques.
We have used Scheme as a vehicle to study problem solving techniques
such as the integration of logic and functional programming. We have
also used it as a vehicle to discuss systems programming issues -
particularly with the Indiana folk on continuation based programming.
I am using Scheme to develop an architectural simulator (currently on PCS,
I also plan to port to Chez Scheme on the VAX for more horsepower) for an
"Optically Interconnected Dataflow Signal Processor" which we are
developing on an ONR contract. Interestingly, I am able to simulate
about a 40 node system on my PC with a (marginally) acceptable
throughput.
Elsewhere in TI, we are using Scheme and the MIT Structure and
Interpretation course as one of the offerings in TI's internal
continuing education curiculum. We are also developing our own course
at a somewhat lower level in programming with Scheme.
I am also aware of a number of other projects which are using Scheme for
developing expert systems or simulation for various purposes. I don't
know details on many of them. Hopefully some of them will repsond
separately.
Altogether, I would say that at least a few hundred persons at TI have
had at least an introductory course which involves Scheme. I'm not sure
how many projects are actively using it, but there are several.
--Don
-------
∂24-Feb-86 1131 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU named-lambda
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 24 Feb 86 11:30:54 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 24 FEB 86 14:31:01 EST
Date: 24 Feb 1986 13:32 EST (Mon)
Message-ID: <JINX.12185966339.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: rrrs-authors@MC.LCS.MIT.EDU
Subject: named-lambda
Maybe somebody can explain why REC is superior to NAMED-LAMBDA. I'm
not particularly attached to NAMED-LAMBDA, but I just don't see any
difference between both (except that I consider REC considerably
uglier).
They are special forms anyway, not essential special forms, and as I
understand it, the only effect of having them on the report is that
the name can mean nothing else (reserved for that purpose if at all).
What I object to is having define by default use REC or NAMED-LAMBDA
rather than LAMBDA (p 18. MIT AI-Memo 848 version).
∂24-Feb-86 1536 @MC.LCS.MIT.EDU:Haddock%ti-csl.csnet@CSNET-RELAY.ARPA Re: Who Is Using Scheme? For What?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 24 Feb 86 15:36:27 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 24 Feb 86 17:35:36 EST
Received: from ti-csl by csnet-relay.csnet id ab00901; 24 Feb 86 17:36 EST
Received: by tilde id AA12842; Mon, 24 Feb 86 15:20:16 cst
Date: Mon 24 Feb 86 15:09:42-CST
From: Rusty (Fe2O3)Haddock (N. Atlantic fish) <Haddock%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Re: Who Is Using Scheme? For What?
To: Scheme%mc.lcs.mit.edu@CSNET-RELAY.ARPA
In-Reply-To: <860224160818.006238@CISL-SERVICE-MULTICS.ARPA>
Message-Id: <12185994981.14.HADDOCK@CSL60>
>Question: Does the TI PC-SCHEME work on Zenith Z-100s
running MSDOS version 2?
Sorry, but PCS doesn't due to the Zenith Z-100 not having a BIOS (in the
I/O areas) similar enough to the IBM-PC (TI's is close, just moves the
vectors around and sometimes expects arguments in different registers) .
Most everything on this Zenith model, as I understand it, uses ESCape
sequences to hand screen functions as well as some keyboard functions.
It would entail some major work to modify the current PCS to work on the
Z-100. As an employee of Texas Instruments I have looked into this
problem and found no quick or painless way around the Z-100.
-Rusty-
================================================================
*hardcopy* *electr{onic, ic}*
Rusty Haddock ARPA: HADDOCK%TI-CSL@CSNET-RELAY.ARPA
POB 226015 M/S 238 CSNET: HADDOCK@TI-CSL
Texas Instruments Inc. USENET: {ut-sally,convex!smu,texsun}!ti-csl!haddock
Dallas, Texas VOICE: (214) 995-0330
75266
-------
∂24-Feb-86 1833 @MC.LCS.MIT.EDU:Swenson.Multics@cisl-service-multics.ARPA Re: Who Is Using Scheme? For What?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 24 Feb 86 18:33:08 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 24 Feb 86 21:32:39 EST
Received: from cisl-service-multics.arpa by CSNET-RELAY.ARPA id a002763;
24 Feb 86 21:08 EST
Acknowledge-To: "Eric J. Swenson" <Swenson@CISL-SERVICE-MULTICS.ARPA>
Date: Mon, 24 Feb 86 21:03 EST
From: "Eric J. Swenson" <Swenson@cisl-service-multics.ARPA>
Subject: Re: Who Is Using Scheme? For What?
To: Rusty Haddock <Haddock%ti-csl.csnet@CSNET-RELAY.ARPA>
cc: Scheme%mc.lcs.mit.edu@CSNET-RELAY.ARPA
In-Reply-To: Message of 24 Feb 86 16:09 EST from "Rusty Haddock"
Message-ID: <860225020338.096619@CISL-SERVICE-MULTICS.ARPA>
Ok, thanks for the info on PCS and the Z-100.
∂24-Feb-86 1854 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU numeric predicates
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 24 Feb 86 18:54:40 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 24 FEB 86 20:55:46 EST
Date: 24 Feb 1986 20:56 EST (Mon)
Message-ID: <JINX.12186047225.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: rrrs-authors@MC.LCS.MIT.EDU
Subject: numeric predicates
How come we have 2 versions of every possible predicate (> and >?,
etc.)? It seems silly to me. Could we drop one of the two? Does
anybody feel strongly about this?
∂24-Feb-86 1904 JAR@MC.LCS.MIT.EDU flush object-hash
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 24 Feb 86 19:01:07 PST
Date: Mon, 24 Feb 86 20:52:56 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: flush object-hash
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].829433.860224.JAR>
I think the section on "the object table" should be flushed. It's
apologetic and unmotivated. It is a fait accompli unless someone
objects [sic] immediately AND rewrites the section.
∂24-Feb-86 1921 @MC.LCS.MIT.EDU:GJS%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Re: numeric predicates
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 24 Feb 86 19:21:00 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 24 FEB 86 22:21:23 EST
Date: Mon 24 Feb 86 22:22:37-EST
From: "Gerald Jay Sussman" <GJS%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
Subject: Re: numeric predicates
To: JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU, rrrs-authors@MC.LCS.MIT.EDU
In-Reply-To: <JINX.12186047225.BABYL@MIT-OZ>
Message-ID: <12186062869.11.GJS@OZ.AI.MIT.EDU>
I feel strongly that we should have >, <, =, because I used them in
S&I. I see no reasons why we should not also have other people's
favorites.
-------
∂24-Feb-86 2117 @MC.LCS.MIT.EDU:ucsbcsl!image!zeger@ucbvax.berkeley.edu Re: Who is using Scheme? For What?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 24 Feb 86 21:16:45 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 25 Feb 86 00:16:02 EST
Received: from ucbvax.berkeley.edu by CSNET-RELAY.ARPA id a000649;
24 Feb 86 23:47 EST
Received: by ucbvax.berkeley.edu (5.45/1.9)
id AA09340; Mon, 24 Feb 86 20:42:32 PST
Received: from image.UCSB (image.ARPA) by ucsbcsl.UCSB (4.12-sdp/3.0.UCSB-sdp)
id AA22913; Mon, 24 Feb 86 13:24:42 pst
Received: by image.UCSB (2.0/2.0.UCSB-sdp)
id AA07510; Mon, 24 Feb 86 13:25:14 pst
Date: Mon, 24 Feb 86 13:25:14 pst
From: Ken Zeger <ucsbcsl!image!zeger@ucbvax.berkeley.edu>
Posted-Date: Mon, 24 Feb 86 13:25:14 pst
Message-Id: <8602242125.AA07510@image.UCSB>
To: Scheme%MIT-MC%csnet-relay@CSNET-RELAY.ARPA
Subject: Re: Who is using Scheme? For What?
I alone am using scheme at UCSB (University of California, Santa Barbara).
I use it in my speech coding research, and for genearl programming purposes.
I've been trying to get others to try it out with little success. There seems
to be some here that enjoy Franz Lisp that they learned in CS course taught.
My address is ucbvax!zeger%image@ucsbcsl.ARPA
Ken Zeger (805)-685-2676
∂24-Feb-86 2330 @MC.LCS.MIT.EDU:andy@aids-unix Scheme use
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 24 Feb 86 23:30:46 PST
Received: from aids-grape.ARPA by MC.LCS.MIT.EDU 25 Feb 86 02:30:27 EST
Date: 24 Feb 1986 22:43-PST
From: andy@aids-unix.ARPA (Andy Cromarty)
Subject: Scheme use
To: Scheme@mit-mc
Cc: andy@aids-unix.ARPA
The computer systems group at Advanced Decision Systems (ADS) in
Mountain View, CA, is using Scheme for a variety of purposes:
o As a systems programming language
o As a vehicle for language design research
o As an implementation language for testbed development
o As a matter of moral principle
Two specific ways in which we are employing Scheme that may be of
interest are:
o As the implementation language for a heterogeneous distributed
systems testbed, and correspondingly,
o As the language substrate into which we embed programming language
constructs for distributed processing, as we design them, for study
and use.
(Some of you may not know ADS. Formerly known as Advanced Information
& Decision Systems, ADS likely has the distinction -- some would say the
"dubious distinction" -- of being the largest concentration of DoD-relevant
applied AI expertise in the world. We also do commercial AI work. We are
100% employee-owned, and for the most part we are engaged in contract R&D.
End of advertisement.)
Our Scheme-hacking staff includes people who learned Scheme both at MIT
in 6.001 and at Indiana under Friedman et alia, as well as designers
and implementors of other large non-Scheme LISPs. Needless to say, this
makes for some interesting (perhaps that should read "raging") ethical
debates during group design meetings.
We currently employ four Schemes to varying extents:
o MIT C-Scheme, which we have retargeted for the Pyramid 90X and
SUN-3 in addition to using it on a VAX 11/780. (We've already
provided the trivial SUN-3 mods to SUN, and will be shipping the
lot of them back to MIT soon for redistribution, along with a
package that brings MIT C-Scheme up to the RRRS standard.)
o Indiana's Scheme-84, which we have running on all the above
machines, with a port to the Lisp Machine marginally in progress.
(We also have some mods to the Scheme-84 compiler in completion
now that bring it more in line with the RRRS standard.)
o MacScheme for the Apple Macintosh. (Will, you did a nice job;
no mods on this one yet.)
o A Scheme compiler/interpreter we've written ourselves and on which
work is actively under way. More details will follow when we feel
we have something significant to contribute.
We also have a Butterfly processor and expect to use BBN's Scheme for
the Butterfly whenever it emerges from the cocoon, so to speak
(sorry, bad pun), and TI PC Scheme is or soon will be on order.
cheers, asc
p.s. I recently convinced a friend and collleague to use Scheme as
the implementation language for a commercial dial-in system
providing economic modeling services. (He used TI's PC Scheme.)
The demo was to be today; if he made the deadline, I imagine that
must represent one of the first practical commercial uses of Scheme.
∂25-Feb-86 0340 @MC.LCS.MIT.EDU:TIM%upenn.csnet@CSNET-RELAY.ARPA who's using Scheme
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Feb 86 03:40:14 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 25 Feb 86 06:40:05 EST
Received: from upenn by csnet-relay.csnet id bj03692; 25 Feb 86 6:41 EST
From: Tim Finin <Tim%upenn.csnet@CSNET-RELAY.ARPA>
Subject: who's using Scheme
To: scheme@mc.lcs.mit.edu
Date: Mon, 24 Feb 86 14:36 EST
At Penn we are using Scheme as a major component of our introductory
programming languages courses at both the graduate and undergraduate level.
Our first undergraduate CIS course is still being offered using Pascal, but
the second CIS course (taken primarily be second semester freshman) now uses
TI's PCS Scheme and Sussman and Abelson's book. This course is currently
being taught be Bonnie Webber and myself. We try to cover all of the book
and some additional material on strongly typed languages and concurrency.
I'm interested in sharing information, assignment ideas, interesting exam
problems, etc. with others using Scheme in early undergraduate courses.
Tim
∂25-Feb-86 0451 @MC.LCS.MIT.EDU:ramsdell%linus@mitre-bedford.ARPA named-lambda
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Feb 86 04:51:22 PST
Received: from mitre-bedford.ARPA by MC.LCS.MIT.EDU 25 Feb 86 07:51:48 EST
Organization: The MITRE Corp., Bedford, MA
Received: by linus.MENET (4.12/4.7)
id AA03869; Tue, 25 Feb 86 07:52:23 est
Date: Tue, 25 Feb 86 07:52:23 est
From: John D. Ramsdell <ramsdell%linus@mitre-bedford.ARPA>
Posted-Date: Tue, 25 Feb 86 07:52:23 est
Message-Id: <8602251252.AA03869@linus.MENET>
To: rrrs-authors@mit-mc.ARPA
Subject: named-lambda
If we decide to dump NAMED-LAMBDA in favor of REC,
why not dump BEGIN and SEQUENCE in favor of LET()?
I worry about trying to decide issues already agreed
upon, instead of clarifing nebulous issues in RRRS.
On one of those issues, EQ? and EQV? semantics, I
vote the straight JAR line.
John
∂25-Feb-86 0544 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU numeric predicates
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Feb 86 05:44:23 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 25 FEB 86 08:22:46 EST
Date: 25 Feb 1986 08:23 EST (Tue)
Message-ID: <JINX.12186172344.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Gerald Jay Sussman <GJS%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
Cc: JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU, rrrs-authors@MC.LCS.MIT.EDU
Subject: numeric predicates
In-reply-to: Msg of 24 Feb 1986 22:22-EST from Gerald Jay Sussman <GJS%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
I feel strongly that we should have >, <, =, because I used them in
S&I. I see no reasons why we should not also have other people's
favorites.
I think in the case of procedures the issue is not as important as in
the case of special forms, since any portable code could at the very
beginning define all the preferred names in terms of the standard
ones. It seems silly, however, to require both sets of names, thus I
was wondering whether anybody cares for either set. Given that you
care for the non-question mark flavor, could we drop the question mark
variety?
∂25-Feb-86 1216 JAR@MC.LCS.MIT.EDU Things used in S&ICP
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Feb 86 12:16:25 PST
Date: Tue, 25 Feb 86 15:16:56 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: Things used in S&ICP
To: GJS@OZ.AI.MIT.EDU
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Mon 24 Feb 86 22:22:37-EST from Gerald Jay Sussman <GJS%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
Message-ID: <[MC.LCS.MIT.EDU].830307.860225.JAR>
Date: Mon 24 Feb 86 22:22:37-EST
From: Gerald Jay Sussman <GJS%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
I feel strongly that we should have >, <, =, because I used them in
S&I. I see no reasons why we should not also have other people's
favorites.
Speaking of what's in S&I, there certainly are many things used in the
book that AREN'T described in the RRRS. Namely, these special forms:
COLLECT
CONS-STREAM
DELAY
DEFINE-MACHINE
MAKE-ENVIRONMENT
and these bindings:
ATOM?
EMPTY-STREAM?
ERROR
EVAL
EXPLODE
FORCE
GET
HEAD
MAPC
IMPLODE
MAPCAR
PRINC
PRINT
PUT
TAIL
THE-EMPTY-STREAM
USER-INITIAL-ENVIRONMENT
I would like to hear a principled argument for including or not
including these various things in the RRRS. (Not a separate argument
for each one, please!) I don't much care what position is taken so long
as it's pretty much consistent. The current RRRS is not consistent,
since it includes SEQUENCE (non-essentially) only because it's in S&I,
but doesn't even include the trivial but important special forms DELAY
and CONS-STREAM.
Suggestion: document them all, each one very briefly, in an appendix, as
non-essential features.
∂25-Feb-86 1527 @MC.LCS.MIT.EDU:Camp%ti-csl.csnet@CSNET-RELAY.ARPA PC SCHEME UTILITIES AND ON-LINE HELP
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Feb 86 15:26:44 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 25 Feb 86 17:26:32 EST
Received: from ti-csl by csnet-relay.csnet id ag09166; 25 Feb 86 16:03 EST
Received: by tilde id AA01226; Tue, 25 Feb 86 09:00:32 cst
Date: Tue 25 Feb 86 08:49:58-CST
From: Clyde <Camp%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: PC SCHEME UTILITIES AND ON-LINE HELP
To: scheme%mit-mc@CSNET-RELAY.ARPA
Cc: Camp%ti-csl.csnet@CSNET-RELAY.ARPA
Message-Id: <12186187998.74.CAMP@CSL60>
For anyone seriously (or unseriously) using PCS on the TI Professional
Computer, I have a written a set of utilities which make some of the systems
functions easier to use. The utilities include procedures to:
- easily create/delete popup and non-popup windows as well as manipulate
their attributes
- pretty-print or verbatum-print source files to the screen or printer
- set-up the 850 or 855 printer modes
- easily interact with the keyboard at the keystroke level
- edit files with the editor of your choice (PFM, WS, PMATE, whatever) and
then load, compile, or fsl them automatically.
Online HELP and user's manual are included. The procedures are:
[8] (help1)
SCHEME UTILITY PACKAGE #1 (c) Clyde R. Camp
v 3.0 12-18-85
SCREEN: (pp←file source-filespec [output-port/file [line-length]])
(show←file source-filespec [output-port/file [line-length]])
WINDOWS: (make-static-window name top left bot right [text border])
(inside window) (window-pixil-size window) (clear-text [window])
(make-popup-window name top left bot right [text [border]])
(delete-popup-window name) (set-text attr1 [attr2 [window]])
(set-border attr1 [attr2 [window]])
CONSOLE: (split-console at-line) (reset-console) (get-console-key [port])
(wait-for-key [port]) (getchar [port]) (was-key? char [port])
PRINTER: (print←file source-filespec [line-length])
(set850! 'parm ['parm.....]) (set855! 'mode ['parm.....])
MISC: (beep) (help1) (ed/ld/cmp/el/ec/ef/cf/fsl [filename])
***default-editor***: edit.exe ***default-memory-size***: 8190
***default-file*** : test.s
===============================================================================
For new scheme'ers using the TIPC I have an on-line help facility which
condenses the language reference manual into a (approx) 60K byte syntax and
information manual.
The procedures are organized into generic classes such as WINDOWS, LISTS,
NUMBERS, GRAPHICS, I/O, etc. A transcript of a typical usage follows:
[3] (help)
PCS ON-LINE VERBOSE HELP Version 1.2 01-09-86
(C) Copyright 1985 by Texas Instruments
All Rights Reserved
(help 'foo) where foo is a valid symbol will return the proper syntax
for the function foo or a notification that it is unbound or
bound in a specific environment
(help 'class) where class is one of the following classes of procedures
will return the syntax of all functions within that class
CONTROL ENVIRONMENTS FLUIDS GLOBALS SYSTEM
DEBUG PREDICATES LISTS SYMBOLS NUMBERS
VECTORS CHARACTERS STRINGS WINDOWS I/O
GRAPHICS STREAMS SCOOPS ENGINES AUTOLOAD
(help 'taciturn) will load a smaller help file with syntax only
[4] (help 'fluids)
(FLUID VAR)
(FLUID-BOUND? VAR)
(FLUID-LAMBDA (VAR ...) EXP1 ...)
(FLUID-LET ((VAR FORM) ...) EXP1 ...)
(SET-FLUID! VAR OBJ)
(SET! (FLUID VAR) EXP)
INPUT-PORT
OUTPUT-PORT
SCHEME-TOP-LEVEL
[5] (help 'scheme-top-level)
SCHEME-TOP-LEVEL
This fluid variable is bound to the value of the standard read-eval-print
loop.
It can be re-bound to a user-defined read-eval-print loop if desired. (reset)
will return to this binding. To return the binding to the standard r-e-p
loop,
use (reset-scheme-top-level).
(define user-loop (lambda (...)
(fluid-let ((scheme-top-level #!false))
(call/cc (lambda (k)
(set! (fluid scheme-top-level)
(lambda () (k '())))))
... body of REP loop ...
[6] (help 'graphics)
All of the graphics functions are autoloaded. See AUTOLOAD.
(CLEAR-GRAPHICS)
(CLEAR-POINT X Y)
(DRAW-BOX-TO X Y)
(DRAW-FILLED-BOX-TO X Y)
(DRAW-LINE-TO X Y)
(DRAW-POINT X Y)
(GET-VIDEO-MODE)
(IS-POINT-ON? X Y)
(POSITION-PEN X Y)
(SET-PALETTE! VALUE DISPLAY-VALUE)
(SET-PEN-COLOR! COLOR)
(SET-VIDEO-MODE! N)
*GRAPHICS-COLORS*
For those with smaller systems there is a smaller version (about 20K bytes)
which has syntax only.
- Clyde Camp
Texas Instruments MS238
P.O.Box 226015
Dallas, TX 75266
(214) 995-0407
-------
∂25-Feb-86 1547 @MC.LCS.MIT.EDU:Ferguson%ti-csl.csnet@CSNET-RELAY.ARPA Re: Who Is Using Scheme? For What?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Feb 86 15:47:29 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 25 Feb 86 17:27:00 EST
Received: from ti-csl by csnet-relay.csnet id am09166; 25 Feb 86 16:07 EST
Received: by tilde id AA11237; Tue, 25 Feb 86 14:20:19 cst
Date: Tue 25 Feb 86 14:09:33-CST
From: Ed <Ferguson%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Re: Who Is Using Scheme? For What?
To: SCHEME%MIT-MC@CSNET-RELAY.ARPA
In-Reply-To: <12184956321.17.OXLEY@CSL60>
Message-Id: <12186246175.15.FERGUSON@CSL60>
I have used Scheme to demonstrate discrete simulation in LISP. I made a
presentation last November at the Expert Systems and Simulation Models
Seminar in Tucson that included the source text for two versions of a
discrete simulation package: event scheduling based on closures and
processing interaction based on continuations. About 200 lines of Scheme
suffice to illustrate the basic control mechanisms for a simulator. (A
copy of my foils (suitable for input to LaTEX) and the Scheme text is
available upon request on an "as is" basis.)
Ed
================================================================
Ed Ferguson ARPA: FERGUSON%TI-CSL@CSNET-RELAY.ARPA
Texas Instruments Inc. CSNET: FERGUSON@TI-CSL
POB 226015, M/S 238 USENET: {ut-sally,convex!smu,texsun}!ti-csl!ferguson
Dallas, Texas 75266 VOICE: (214) 995-0348
-------
∂25-Feb-86 1657 JAR@MC.LCS.MIT.EDU EQ? non-essential?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Feb 86 16:57:23 PST
Date: Tue, 25 Feb 86 19:57:37 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: EQ? non-essential?
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of 20 Feb 1986 00:20 EST (Thu) from Bill Rozas <JINX%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
Message-ID: <[MC.LCS.MIT.EDU].830587.860225.JAR>
We are still deadlocked on the 2 or 3 questions surrounding EQ?. No
consensus is arising, except that implementations may decide on the
result of (EQ? (LAMBDA (X) X) (LAMBDA (Y) Y)), and that characters
should have the same status as numbers.
A long argument between myself and a unnamed proponent of the ability to
test object identity resulted in the following proposal which would
make us both happy: make EQ? be a non-essential feature of the language.
Require that implementations which have it guarantee that it behave as
described in the current RRRS (e.g. (EQ? X X) would always hold).
Implementations which wish to do clever things with procedures in
violation of the implied invariant, and documentors who do not want to
be embarrassed by having something so unclean and ill-specified in such
a prominent position in the language, may simply choose to not implement
(describe) EQ?. A denotational semantics of the essential subset would
not have to adjoin locations to numbers and procedures, although one
which wanted to describe EQ? invariants would.
If, as Sussman once pointed out to me, an "object model" of the world is
deeply embedded in S&ICP and the way Scheme is taught, then this would
be better than making (EQ? X X) be implementation-dependent, although I
would still favor the latter if EQ? were essential.
The effect of this is that while all existing implementations would stay
the same and implement EQ? as always, experimental implementations of
the language which take liberties with procedures will still be allowed
to call themselves "scheme" rather than "a variant of scheme not having
EQ?". 6.001-style courses using such implementations will have to get by
without it, somehow.
(Obviously this would also make MEMQ and ASSQ also non-essential.)
∂25-Feb-86 2136 @MC.LCS.MIT.EDU:cpd@LOCUS.UCLA.EDU Re: Who is using scheme?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Feb 86 21:36:17 PST
Received: from LOCUS.UCLA.EDU by MC.LCS.MIT.EDU 26 Feb 86 00:36:04 EST
Date: Tue, 25 Feb 86 21:13:06 PST
From: Charles Dolan <cpd@LOCUS.UCLA.EDU>
To: scheme@mit-mc
Subject: Re: Who is using scheme?
Message-ID: <509778786-3011-cpd@ZEUS.LOCUS.UCLA.EDU>
At the Hughes Aircraft AI Center we are using MacScheme for research in:
natural language,
learning, and
knowledge based decisions aids.
The we are using have 2Mb or memory and 20Mb disks. The main reason
we are using Scheme is that it make agenda based programming easier.
Charles Dolan
Hughes AI Center
23901 Calabasas Rd.
Calabasas, CA 91302-1579
cpd@locus.ucla.edu
∂25-Feb-86 2341 @MC.LCS.MIT.EDU:entropy!jam@uw-beaver.arpa Scheme for a Symbolics
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Feb 86 23:41:36 PST
Received: from uw-beaver.arpa by MC.LCS.MIT.EDU 26 Feb 86 02:24:42 EST
Received: by uw-beaver.arpa (4.42/4.2)
id AA08139; Tue, 25 Feb 86 23:29:30 PST
Return-Path: <entropy!jam@uw-beaver.arpa>
Received: by entropy.UUCP (5.31/1.0.Entropy)
id AA23296; Tue, 25 Feb 86 23:23:34 PST
Date: Tue, 25 Feb 86 23:23:34 PST
From: John Alan McDonald <entropy!jam@uw-beaver.arpa>
Posted-Date: Tue, 25 Feb 86 23:23:34 PST
Message-Id: <8602260723.AA23296@entropy.UUCP>
To: scheme@mit-mc
Subject: Scheme for a Symbolics
I would appreciate any information about implementations of Scheme
that run on a Symbolics or implementations of Scheme in Common Lisp
or Zetalisp.
John Alan McDonald
Statistics, GN-22, U of W
Seattle, Wa. 98195
(206) 545 7438
jam%entropy@uw-beaver.arpa
{decvax,ihnp4,ucbvax!lbl-csam}!uw-beaver!entropy!jam
∂26-Feb-86 1243 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: Things used in S&ICP
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 26 Feb 86 12:43:14 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 26 Feb 86 15:29:24 EST
Received: from ti-csl by csnet-relay.csnet id ab08802; 26 Feb 86 14:36 EST
Received: by tilde id AA08980; Wed, 26 Feb 86 09:00:17 cst
Date: Wed 26 Feb 86 08:49:44-CST
From: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Re: Things used in S&ICP
To: JAR%MC.LCS.MIT.EDU%ti-csl.csnet@CSNET-RELAY.ARPA,
GJS%OZ.AI.MIT.EDU%ti-csl.csnet@CSNET-RELAY.ARPA
Cc: RRRS-AUTHORS%MC.LCS.MIT.EDU%ti-csl.csnet@CSNET-RELAY.ARPA,
Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
In-Reply-To: <[MC.LCS.MIT.EDU].830307.860225.JAR>
Message-Id: <12186450098.45.BARTLEY@CSL60>
> Mail-From: MAIL created at 26-Feb-86 02:08:59
> From: Jonathan A Rees <JAR%MC.LCS.MIT.EDU@tilde>
>
> Date: Mon 24 Feb 86 22:22:37-EST
> From: Gerald Jay Sussman <GJS%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
>
> I feel strongly that we should have >, <, =, because I used them in
> S&I. I see no reasons why we should not also have other people's
> favorites.
>
> Speaking of what's in S&I, there certainly are many things used in the
> book that AREN'T described in the RRRS. Namely, these special forms:
> ...
> Suggestion: document them all, each one very briefly, in an appendix, as
> non-essential features.
I like this suggestion. Like most implementors, we will want to have
a ``compatibility package'' for use with the book, but it seems
unnecessary to ``grandfather'' all of its forms and functions in the
standard itself. Recognizing the book's variants in a non-binding
appendix will give notice that those names have unofficial but widely
observed meanings. I also sense that the Scheme community may be
ready to eliminate some of the historical oddities in the compromise
worked out at Brandeis.
I worry, though, that other dialects may feel slighted. Do we want to
list Scheme84's or T's variants in an appendix as well? I don't think
so -- I feel that S&ICP is a unique case -- but there may be disagreement.
Thus, I vote (mildly) for the `=?' names rather than the `=' names. I
also intend to continue to support the S&ICP names.
Regards,
David Bartley
-------
∂26-Feb-86 1313 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: EQ? non-essential?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 26 Feb 86 13:12:38 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 26 Feb 86 16:12:30 EST
Received: from ti-csl by csnet-relay.csnet id ag08802; 26 Feb 86 14:40 EST
Received: by tilde id AA11416; Wed, 26 Feb 86 10:40:12 cst
Date: Wed 26 Feb 86 10:34:34-CST
From: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Re: EQ? non-essential?
To: JAR%MC.LCS.MIT.EDU%ti-csl.csnet@CSNET-RELAY.ARPA,
RRRS-AUTHORS%MC.LCS.MIT.EDU%ti-csl.csnet@CSNET-RELAY.ARPA
Cc: Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
In-Reply-To: <[MC.LCS.MIT.EDU].830587.860225.JAR>
Message-Id: <12186469182.45.BARTLEY@CSL60>
Here are some comments on recently raised issues...
(1) I agree with JAR that OBJECT-HASH should be flushed.
(2) I still believe strongly that EQ? should amount to a pointer test
and that the standard should specify the domain over which it is
defined---symbols, booleans, (), and mutable objects (pairs, vectors,
strings, and ports). It should be undefined (implementation-dependent
but not an error) for numbers, characters, closures, and
continuations.
Bert asks whether the optimization this allows is worth the loss of
the ability to compare procedures which represent abstract data. I
have to say yes for two reasons. First, some other predicate than EQ?
makes better sense for such tests. Second, the inhibition on the
optimizing compiler is pretty strong since the EQ? test may not be
lexically visible. The compiler can't always know when it is safe to
split and when it isn't. Thus, I oppose the idea that (EQ? X X)
should always be true.
I also disagree strongly with JAR's latest suggestion that EQ? be made
non-essential. Doing so doesn't solve the problem, it just passes the
buck!
>The effect of this is that while all existing implementations would stay
>the same and implement EQ? as always, [...]
Not so! I've explained why I want EQ? and why ``implementing EQ? as
always'' is inconsistent with the semantics that (EQ? X X) ==> #!TRUE
when you have an optimizing compiler.
(3) I agree with JAR and others that EQV? should be independent of the
implementation. As I understand it, this amounts to saying the use of
EQV? is an error except for a specified domain. My previous position
was that it should be implementation-dependent over all but the
(same?) domain. I subscribe to the statement ``(EQ? X Y) implies
(EQV? X Y) whenever (EQV? X Y) is defined.'' I'd like to see EQV?
extend EQ? to encompass exact numbers and characters but not closures
and continuations.
(4) Ramsdell has raised the notion that (BEGIN ...) is redundant with
(LET () ...). This is not true for those of us that support the
MIT-style embedded DEFINE and first-class environments.
Regards,
David Bartley
-------
∂27-Feb-86 0941 @MC.LCS.MIT.EDU:veach%ukans.csnet@CSNET-RELAY.ARPA Use of Scheme.
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 27 Feb 86 09:41:46 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 27 Feb 86 12:03:45 EST
Received: from ukans by csnet-relay.csnet id aa19363; 27 Feb 86 11:46 EST
Date: Wed, 26 Feb 86 12:22:55 CST
From: "Glenn O. Veach" <veach%ukans.csnet@CSNET-RELAY.ARPA>
To: SCHEME%mc.lcs.mit.edu@CSNET-RELAY.ARPA
cc: OXLEY%%ti-csl.csnet@CSNET-RELAY.ARPA
Subject: Use of Scheme.
This past year at the University of Kansas we used Scheme in two
classes. In an undergraduate "Programming Languages" class we
went through Abelson and Sussman's book while using Scheme for
homework and class projects. In a graduate level "Artificial
Intelligence" class we went through Kowalski's book and assigned
a project to develop a Horne clause theorem prover which some
implemented using Scheme. We are now trying to a curriculum
for our "Introductory Programming" course in which we would use
MacScheme (we now use Pascal) and would use Abelson and Sussman
as a text (probably not the entire book). We would hope to use
the remaining chapters of the text for our second semester
programming course.
We are of course encountering some resistance as we try to forge
ahead with Lisp as a basic instructional language. Has anyone
been involved with the review process of ACM or IEEE for CS or
ECE programs and suggested the use of Lisp as a basic language?
What are some of the more compelling arguments for and against
such an effort? If anyone could direct me to any B-Boards on
ARPA net which would appreciate such a discussion I would appreciate
it. I intend to send such an inquiry to AIList and Prolog.
Glenn O. Veach
Artificial Intelligence Laboratory
Department of Computer Science
University of Kansas
Lawrence, KS 66045-2192
(913) 864-4482
veach%ukans.csnet@csnet-relay
∂27-Feb-86 1226 @MC.LCS.MIT.EDU:JBS@DEEP-THOUGHT.MIT.EDU Use of Scheme.
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 27 Feb 86 12:25:56 PST
Received: from DEEP-THOUGHT.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 27 FEB 86 15:12:47 EST
Date: Thu 27 Feb 86 15:14:02-EST
From: Jeff Siegal <JBS@DEEP-THOUGHT.MIT.EDU>
Subject: Use of Scheme.
To: SCHEME@MC.LCS.MIT.EDU
In-Reply-To: Message from ""Glenn O. Veach" <veach%ukans.csnet@CSNET-RELAY.ARPA>" of Thu 27 Feb 86 13:00:39-EST
Message-ID: <12186771281.32.JBS@DEEP-THOUGHT.MIT.EDU>
I don't think I've seen anyone mention this, but of course MIT uses
Scheme for 6.001, "Structure and Interpretation of Computer Programs"
Jeff Siegal - MIT EECS
-------
∂27-Feb-86 1519 JAR@MC.LCS.MIT.EDU Scheme in Common Lisp
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 27 Feb 86 15:19:36 PST
Date: Thu, 27 Feb 86 18:19:27 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: Scheme in Common Lisp
To: entropy!jam@UW-BEAVER.ARPA
cc: SCHEME@MC.LCS.MIT.EDU
In-reply-to: Msg of Tue 25 Feb 86 23:23:34 PST from John Alan McDonald <entropy!jam at uw-beaver.arpa>
Message-ID: <[MC.LCS.MIT.EDU].832991.860227.JAR>
Date: Tue, 25 Feb 86 23:23:34 PST
From: John Alan McDonald <entropy!jam at uw-beaver.arpa>
I would appreciate any information about implementations of Scheme
that run on a Symbolics or implementations of Scheme in Common Lisp
or Zetalisp.
Implementation: CLSCH (Scheme embedded in Common Lisp)
Implemented by: Jonathan Rees
Support: Unsupported, although I'll probably continue to improve it.
No promises.
Hardware: Will run, I hope, in any implementation of Common Lisp; has
been tested in Symbolics Common Lisp and TOPS-20 CLISP.
Availability: Free. Distributed as source via electronic mail or FTP.
May eventually become part of Common Lisp "Yellow Pages."
Dialect: Subset. All of the essential features of RRRSS exist, except
for a correct CALL-WITH-CURRENT-CONTINUATION; also some of the
rest of RRRSS, and most of the S&ICP dialect.
Intended use: Running existing scheme programs in any Common Lisp. Not an
ideal development system, since debugging tools are weak.
Implementation: Low-tech. A simple compiler translates Scheme into Common
Lisp, making sure that variable binding and tail recursion
are done right. The output of the compiler can be interpreted
by a CL interpreter or compiled by a CL compiler.
Remarks: I did this mostly for my own personal use. Maybe other people
will find it useful too.
Contact: Jonathan Rees (JAR@MC.LCS.MIT.EDU), MIT Artificial Intelligence
Laboratory, 545 Technology Square, Cambridge MA 02139,
(617) 253-8581.
A list of blurbs of this sort for all known scheme implementations
(except MIT scheme) is available in the file "SCHEME; SCHEME IMPLS" on
MIT-MC.
∂27-Feb-86 1548 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: named-lambda, etc
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 27 Feb 86 15:47:54 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 27 Feb 86 18:22:21 EST
Received: from tektronix by csnet-relay.csnet id aj22696; 27 Feb 86 17:54 EST
From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
To: JINX%OZ.AI.MIT.EDU@xx.lcs.mit.edu
Cc: rrrs-authors@mc.lcs.mit.edu
Received: from tekchips by tektronix with smtp ; 26 Feb 86 16:15:36 PST
Comment: Message received over unauthenticated port at tektronix
Received: by tekchips (5.31/5.14), id AA15130; Wed, 26 Feb 86 16:16:47 PST
Message-Id: <8602270016.AA15130@tekchips>
Subject: Re: named-lambda, etc
In-Reply-To: Your message of 24 Feb 1986 13:32 EST (Mon)., <JINX.12185966339.BABYL@MIT-OZ>
Date: 26 Feb 86 16:16:42 PST (Wed)
The only advantages I see to REC over NAMED-LAMBDA are the ability to
say things like
(REC SELF
(VECTOR
(LAMBDA ()
(LET ((X (FOO)))
(VECTOR-SET! SELF 0 (LAMBDA () X))
X))))
and the mnemonically useful relationship between REC and LETREC. (On a close
vote we chose the names REC and LETREC over LABEL and LABELS.)
I see no such advantage to NAMED-LAMBDA over REC. I use REC fairly often
myself, more often than I use CASE, LET*, or internal DEFINE, but I'd be
willing to give it up and use LETREC instead if that's what it takes to
get NAMED-LAMBDA out of the RRRS.
----------------
I support the idea of collecting stuff specific to S&ICP in an appendix.
----------------
I am probably the person who most likes <?, =?, et cetera, out of regard
for the name formation rules. As JINX observes, procedure names are less
important than the names of special forms, so I don't care so much whether
<? et al go or stay.
----------------
JINX also writes:
> What I object to is having define by default use REC or NAMED-LAMBDA
> rather than LAMBDA (p 18. MIT AI-Memo 848 version).
This is a real problem when introducing someone to Scheme, because people
who see the (DEFINE (FOO X) ...) syntax quickly infer that it is the same
as (DEFINE FOO (LAMBDA (X) ...)), and you have to tell them that the two
are slightly different but that you can't explain the difference until
they've learned more of the language. This defeats the very positive
feelings of understanding and mastery that beginning Scheme programmers
would otherwise have.
The main argument that I see for having the alternative DEFINE syntaxes
use REC is that it makes it easier for people to define procedures in
such a way that self-recursive calls can be compiled as simple jumps.
I don't consider this to be a very good argument.
Peace, William Clinger
∂27-Feb-86 1615 @MC.LCS.MIT.EDU,@SU-SCORE.ARPA:starbuck@camelot Scheme use
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 27 Feb 86 16:15:23 PST
Received: from SU-SCORE.ARPA by MC.LCS.MIT.EDU 27 Feb 86 19:01:48 EST
Received: from camelot ([36.48.0.3].#Internet) by SU-SCORE.ARPA with TCP; Thu 27 Feb 86 15:02:02-PST
Received: by camelot with TCP; Thu, 27 Feb 86 14:58:22 pst
Date: 27 Feb 1986 1458-PST (Thursday)
From: Orca.Starbuck@camelot, <starbuck@camelot>
To: scheme%mc.lcs.mit.edu@score
Cc: starbuck@camelot
Subject: Scheme use
As a sophomore at Oberlin College last year, I took two courses that
involved extensive use of Scheme:
1. a course in functional programming, using Abelson & Sussman's book
as the main text. We also used a draft version (?) of a book entitled
Fundamental Abstractions of Programming Languages, by W. Clinger, D.
Friedman, C. Haynes, E. Kohlbecker, and M. Wand. This book was written
for a course at Indiana (natch) on the design and implementation of
programming languages. Our version was copyright 1984. I'd heartily
recommend it to anyone who can get a copy of it.
2. an introductory course in the denotational semantics. For this
course we used M. Gordon's book, The Denotational Description of
Programming Languages, as a basic text, and Stoy's book entitled
Denotational Semantics for more depth. Most of the work in this class
was done directly in Scheme. We wrote general interpreters that took
as input denotational descriptions of a language and returned
interpreters for that language, which made our work in semantics much
easier because we could actually run and debug the semantics for each
language.
There were also other classes at Oberlin involving Scheme, such as
classes in theory and AI. Last year all of our work was done in Scheme
84. I believe that this year they are using Chez Scheme.
You can contact my teacher at the following address:
Prof. Richard Salter
Department of Mathematics
Oberlin College
Oberlin, Ohio 44074
Oberlin is not, as far as I know, on any computer network.
-------
∂28-Feb-86 0354 @MC.LCS.MIT.EDU:JMILLER@OZ.AI.MIT.EDU Re: named-lambda, etc
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 28 Feb 86 03:54:07 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 28 FEB 86 06:54:34 EST
Date: 28 Feb 1986 06:55-EST
Sender: JMILLER@MIT-OZ
Subject: Re: named-lambda, etc
From: JMILLER@MIT-OZ
Reply-To: JMiller%OZ@MC
To: rrrs-authors@MC
Message-ID: <[MIT-OZ]28-Feb-86 06:55:45.JMILLER>
In-Reply-To: <8602270016.AA15130@tekchips>
I vowed never to send a message to this forum, but Will finally
got me. I have been teaching Scheme out of S&ICP for 3 years now
and find that introducing NAMED-LAMBDA simultaneously with LAMBDA
in fact makes most people feel far more comfortable. I introduce
it by explaining that it is sometimes nice for a procedure to
have "a name for itself" as opposed to "a name other things call
it" and use the analogy of nicknames. Most students sigh a large
sigh of relief at this point, since it seems that it fulfills
some need they have for procedures to have names -- I don't know
why they are so firmly convinced that a nameless procedure is
execrable, but it is so! This is not an argument either way
about REC, etc. -- although the notion of a set of names for
each other shared by a group is just a tad harder to explain.
--Jim
∂28-Feb-86 1158 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA publication of RRRS in SIGPLAN Notices
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 28 Feb 86 11:58:10 PST
Received: from GODOT.THINK.COM by MC.LCS.MIT.EDU 28 Feb 86 14:45:34 EST
Received: from guido by GODOT.THINK.COM via CHAOS; Fri, 28 Feb 86 13:47:48 est
Date: Fri, 28 Feb 86 13:49 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: publication of RRRS in SIGPLAN Notices
To: RRRS-AUTHORS@mc.lcs.mit.edu
Cc: gls@THINK-AQUINAS.ARPA
In-Reply-To: <8602201836.AA08527@tekchips>
Message-Id: <860228134934.2.GLS@GUIDO.THINK.COM>
If RRRS is to be published in SIGPLAN Notices, I beg that a short
introduction be added explaining to the general readership why it is
important. I am extremely annoyed at SIGPLAN Notices for publishing
lots of little language definitions that spend two pages explaining the
syntax of arithmetic expressions that turns out to be the same as
everyone else's syntax but spend no prose explaining why I should be
interested in this language.
--Guy
∂28-Feb-86 1204 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA numeric predicates
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 28 Feb 86 12:03:03 PST
Received: from GODOT.THINK.COM by MC.LCS.MIT.EDU 28 Feb 86 14:55:09 EST
Received: from guido by GODOT.THINK.COM via CHAOS; Fri, 28 Feb 86 14:54:43 est
Date: Fri, 28 Feb 86 14:56 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: numeric predicates
To: JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU, rrrs-authors@MC.LCS.MIT.EDU
Cc: gls@THINK-AQUINAS.ARPA
In-Reply-To: <JINX.12186047225.BABYL@MIT-OZ>
Message-Id: <860228145630.7.GLS@GUIDO.THINK.COM>
Date: 24 Feb 1986 20:56 EST (Mon)
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
How come we have 2 versions of every possible predicate (> and >?,
etc.)? It seems silly to me. Could we drop one of the two? Does
anybody feel strongly about this?
This is a good excuse for me to put in my two cents' worth, a few years
too late: I think that putting "?" in the names of all the predicates
is a TERRIBLE idea. Why? Because they make it much harder to read code
out loud. The "-P" convention is at least pronounceable, if visually
bizarre (but I would do away with that too if I could). I will not
entertain counterarguments of the form "But English uses `?' and not
`P'" because English does NOT lump the "?" in with the spelling of the
verb; it is a marker on the entire sentence.
--Guy
∂28-Feb-86 1526 JAR@MC.LCS.MIT.EDU EQ?, again
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 28 Feb 86 15:26:30 PST
Date: Fri, 28 Feb 86 18:26:57 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: EQ?, again
To: gls@AQUINAS.THINK.COM
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Fri 28 Feb 86 16:40 EST from Guy Steele <gls at THINK-AQUINAS.ARPA>
Message-ID: <[MC.LCS.MIT.EDU].834417.860228.JAR>
Date: Fri, 28 Feb 86 16:40 EST
From: Guy Steele <gls at THINK-AQUINAS.ARPA>
Date: Wed, 19 Feb 86 21:37:49 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
I 1. (EQ? (LAMBDA (X) X) (LAMBDA (Y) Y)) ;"Coalescing"
I 2. (EQV? (LAMBDA (X) X) (LAMBDA (Y) Y))
I 3. (LET ((X (LAMBDA (Z) Z))) (EQ? X X)) ;"Splitting"
T 4. (LET ((X (LAMBDA (Z) Z))) (EQV? X X))
I 5. (LET ((X ... any expression evaluating to an exact number ...))
(EQ? X X))
I 6. (EQ? #\X #\X)
It took me a while to figure out how to reconcile your answer to 3 with
your answer to 4. I take it you want procedures to know their identity,
but that you imagine an implementation would still want the liberty to
make (identity-preserving) copies, so EQ? might fail to recognize two
procedures being the same, even though EQV? could succeed?
∂28-Feb-86 1610 @MC.LCS.MIT.EDU:KMP@SCRC-STONY-BROOK.ARPA P?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 28 Feb 86 16:08:06 PST
Received: from SCRC-STONY-BROOK.ARPA by MC.LCS.MIT.EDU 28 Feb 86 19:08:15 EST
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 428075; Fri 28-Feb-86 18:19:15-EST
Date: Fri, 28 Feb 86 18:20 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: P?
To: gls@THINK-AQUINAS.ARPA
cc: JINX@MIT-AI.ARPA, RRRS-AUTHORS@MIT-MC.ARPA
In-Reply-To: <860228145630.7.GLS@GUIDO.THINK.COM>
Message-ID: <860228182054.2.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
For what it's worth, in the original spec for the T dialect that I worked up
in 1981, "?" had an assigned pronunciation. It was explicitly stated that it
should be pronounced "pee". That way, when we said "zero?" out loud in
conversations with non-T-programmers, they would `accidentally' understand us.
After I left, someone (Jonathan?) took this out, probably thinking it was
gratuitous silliness, but in fact I agree with you that pronounceability is
very important to a language and that definition wasn't put there on a whim.
Along the same lines, "!" was given the pronunciation " destructively".
Those who doubt that pronunciation is important should notice that most
natural languages are transmitted primarily verbally (that is, that changes
in language are frequently best described at the acoustic rather than
written level), that psychologists seem to believe that indexing of objects
in the brain is done more on the basis of auditory rather than visual keys
(based on studies of how people mis-remember things), etc.
Those who insist that the morpheme "pee" is somehow less meaningful
than some other token that could have been chosen should ask themselves not
about how English words relate to Latin, but how the creators of Latin came up
with their morphemes.
I believe that a language which cannot conveniently be discussed allowed
[... uh, "aloud" I mean -- i guess I'll leave that typo in to support
my claim two paragraphs above] is doing its prospective programmers a great
disservice... but I think ZERO? looks lots nicer than ZEROP, so my vote is
for changing the pronunciation and leaving the written word as it is.
By the way, T also originally defined very carefully the rules of contraction
so that users would be able to choose consistent function names. It specified,
for example that a function xxx which did
(define (xxx . args) (apply fn EQ? args))
should be called fnQ, and that one that did
(define (xxx . args) (apply fn EQV? args))
should be called fnV and that one that did
(define (xxx . args) (true? (apply fn args)))
should be called fn? . In the case of a "?" ending up in the middle of a token,
it was to migrate to the end, and in the case of a "!" and "?" ending up in a token
(ie, a destructive predicate), the "?" was to precede the "!". Among other things,
this meant that the function which did (MEM EQ? x y) could be written (MEMQ x y)
and the function which did (MEM EQV? x y) could be written (MEMV x y). Further,
(TRUE? (MEM EQV? x y)) = (TRUE? (MEMQ x y)) = (MEM? EQ? (MEMQ? x y)) = (MEMQ? x y).
Personally, I am content to say that "?" does not get attached to any predicate
which has a root which contains no alphabetic characters. That is, that ">" is
allowed to be a contraction for "greater?" rather than just "greater", so ">?"
is like saying "greater??". We used a similar reasoning for not putting "!"
on the end of "SET" in T, since "SET!" is redundant. Any assignment is by
definition destructive and setting an "!" after SET is effectively redundant
and just makes code look ugly. I think the proponents of the name "SET!" would
say that assignments -should- look ugly, and to that I can only say that I
disagree.
Sorry this message got as long as it did, but this is the sort of topic people
don't seem to be able to vocalize their feelings about, so I figured it was
worth doing so just for the record.
-kmp
∂28-Feb-86 1610 JAR@MC.LCS.MIT.EDU S&I's idea of EQ?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 28 Feb 86 16:01:19 PST
Date: Fri, 28 Feb 86 19:01:52 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: S&I's idea of EQ?
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].834462.860228.JAR>
I know Sussman is too shy to send out messages, so I'll repeat what he
told me recently, which is that being able to use EQ? to recognize
particular procedures (i.e. (let ((p (lambda ...))) (eq? p p)) => true)
is deeply and explicitly wired into his book, and into the way he
teaches and programs. For example, see the constraint system, pages
234-240 of Structure & Interpretation, and in particular the definition
of the subprocedure ME of MULTIPLIER, page 237. Therefore he would be
very sad if Scheme changed out from underneath him. He is sick of
moving targets and would like a stable language compatible with what
he's been calling Scheme all these years, even if it has serious
problems.
As another source of argument against the LAMBDA-as-behavior position, I
should say that my reading of the Common Lisp manual is that (let ((p
(lambda ...))) (eq? p p)) must definitely return true. Only numbers are
permitted to fail to be EQ to themselves. So if you believe that Scheme
shouldn't gratuitously differ from CL, then all objects besides numbers
should be "EQ to themselves".
As both Sussman and Halstead have suggested, one option is to have TWO
forms for creating procedures, one which creates a callable <behavior,
location> pair, like the current Scheme and Common Lisp LAMBDA, and
another which only returns the operational behavior, which is the change
to LAMBDA that the Yale, TI, and Tek contingents want to institute.
This would be needed anyhow in those implementations interested in
emulating Common Lisp or a subset of it. I would guess that this would
be easy to do in most existing implementations. If this is agreed to,
then we have a naming problem on our hands, argument over which,
unfortunately, might do this idea in (which one gets the name LAMBDA,
and what should the other one be called?).
Jonathan
∂28-Feb-86 1817 JAR@MC.LCS.MIT.EDU named-lambda, etc
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 28 Feb 86 18:16:38 PST
Date: Fri, 28 Feb 86 14:56:34 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: named-lambda, etc
To: JMiller@OZ.AI.MIT.EDU
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of 28 Feb 1986 06:55-EST from JMILLER at MIT-OZ
Message-ID: <[MC.LCS.MIT.EDU].834126.860228.JAR>
Why not NAMED-CONS, NAMED-VECTOR, NAMED-+, NAMED-READ-CHAR,
NAMED-CALL-WITH-CURRENT-CONTINUATION, NAMED-WITH-INPUT-FILE, etc.?
∂28-Feb-86 1831 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA EQ?, again
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 28 Feb 86 18:30:55 PST
Received: from GODOT.THINK.COM by MC.LCS.MIT.EDU 28 Feb 86 16:39:31 EST
Received: from guido by GODOT.THINK.COM via CHAOS; Fri, 28 Feb 86 16:39:05 est
Date: Fri, 28 Feb 86 16:40 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: EQ?, again
To: JAR@MC.LCS.MIT.EDU, RRRS-AUTHORS@MC.LCS.MIT.EDU
Cc: gls@THINK-AQUINAS.ARPA
In-Reply-To: <[MC.LCS.MIT.EDU].823678.860219.JAR>
Message-Id: <860228164046.1.GLS@GUIDO.THINK.COM>
Date: Wed, 19 Feb 86 21:37:49 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
I 1. (EQ? (LAMBDA (X) X) (LAMBDA (Y) Y)) ;"Coalescing"
I 2. (EQV? (LAMBDA (X) X) (LAMBDA (Y) Y))
I 3. (LET ((X (LAMBDA (Z) Z))) (EQ? X X)) ;"Splitting"
T 4. (LET ((X (LAMBDA (Z) Z))) (EQV? X X))
I 5. (LET ((X ... any expression evaluating to an exact number ...))
(EQ? X X))
I 6. (EQ? #\X #\X)
Let me qualify those five "I" answers. If two things are EQ?, then they
should be operationally identical. (One consequence is that two things
that are EQ? should also be EQV?.) If they are not EQ?, then they might
or might not be operationally identical. The contrapositive is: if two
things are proved in the course of a program execution to be
operationally distinct, then EQ? must consistently be false of them (in
both the future and the past).
--Guy
∂28-Feb-86 1831 ALAN@MC.LCS.MIT.EDU numeric predicates
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 28 Feb 86 18:31:13 PST
Date: Fri, 28 Feb 86 17:11:21 EST
From: Alan Bawden <ALAN@MC.LCS.MIT.EDU>
Subject: numeric predicates
To: gls@AQUINAS.THINK.COM
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU, JINX@OZ.AI.MIT.EDU
In-reply-to: Msg of Fri 28 Feb 86 14:56 EST from Guy Steele <gls at THINK-AQUINAS.ARPA>
Message-ID: <[MC.LCS.MIT.EDU].834331.860228.ALAN>
Date: Fri, 28 Feb 86 14:56 EST
From: Guy Steele <gls at THINK-AQUINAS>
... I think that putting "?" in the names of all the predicates is a
TERRIBLE idea. Why? Because they make it much harder to read code out
loud....
Hmmm... Perhaps we could make it an official convention that the trailing
"?" in many predicate names is -pronounced- "pea"!
∂28-Feb-86 2307 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU named-lambda, etc
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 28 Feb 86 23:07:26 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 1 MAR 86 02:07:58 EST
Date: 1 Mar 1986 02:06 EST (Sat)
Message-ID: <JINX.12187152280.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: JMiller%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU, RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: named-lambda, etc
In-reply-to: Msg of 28 Feb 1986 14:56-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
Date: Friday, 28 February 1986 14:56-EST
From: Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
To: JMiller at OZ.AI.MIT.EDU
cc: RRRS-AUTHORS at MC.LCS.MIT.EDU
Re: named-lambda, etc
Why not NAMED-CONS, NAMED-VECTOR, NAMED-+, NAMED-READ-CHAR,
NAMED-CALL-WITH-CURRENT-CONTINUATION, NAMED-WITH-INPUT-FILE, etc.?
Come on, now. These objects have no good reason to have names
for themselves since they could use them in no way that I can see.
The case is obviously different for procedures.
∂28-Feb-86 2323 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU named-lambda, etc
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 28 Feb 86 23:23:04 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 1 MAR 86 02:23:13 EST
Date: 1 Mar 1986 02:21 EST (Sat)
Message-ID: <JINX.12187154963.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
Cc: rrrs-authors@MC.LCS.MIT.EDU
Subject: named-lambda, etc
In-reply-to: Msg of 26 Feb 1986 19:16-EST from willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
The only advantages I see to REC over NAMED-LAMBDA are the ability to
say things like
(REC SELF
(VECTOR
(LAMBDA ()
(LET ((X (FOO)))
(VECTOR-SET! SELF 0 (LAMBDA () X))
X))))
I hope that we are not requiring implementations to support the above.
It gives the illusion that REC (LETREC) can do something (solving
simultaneous equations) which in fact it (they) cannot do (at least I do
not know how to make them do that, short of changing to normal order
evaluation). If we are not requiring this behavior, the argument is
moot.
and the mnemonically useful relationship between REC and LETREC.
(On a close vote we chose the names REC and LETREC over LABEL and
LABELS.)
REC sounds like WRECK and RECORD to me, not like LETREC. Note that
since LETREC expects a list as its second subform, it syntax could be
trivially extended to support the common case of just one name, and
REC would become unnecessary (also helping GJS's goal of reducing the
number of special forms).
Now really, I don't see why people object to NAMED-LAMBDA (which is
not essential) so violently. I don't love it, but I don't dislike it,
and it seems to me that people have just decided to pick on it for no
good reason, when REC is just as random and considerably less
intuitive.
∂01-Mar-86 2333 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU%mc.lcs.mit.edu@CSNET-RELAY.ARPA EQ? non-essential?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 1 Mar 86 23:33:32 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 2 Mar 86 02:33:16 EST
Received: from ti-csl by csnet-relay.csnet id a003250; 2 Mar 86 2:34 EST
Received: by tilde id AA22080; Sat, 1 Mar 86 21:32:58 cst
Received: from mc.lcs.mit.edu by CSNET-RELAY.ARPA id a001625; 1 Mar 86 21:43 EST
Date: 1 Mar 1986 21:36 EST (Sat)
Message-Id: <JINX.12187365259.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU%xx.lcs.mit.edu@CSNET-RELAY.ARPA>
To: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Cc: RRRS-AUTHORS%MC.LCS.MIT.EDU%ti-csl.csnet@CSNET-RELAY.ARPA
Subject: EQ? non-essential?
In-Reply-To: Msg of 26 Feb 1986 11:34-EST from David Bartley <Bartley%ti-csl.csnet at CSNET-RELAY.ARPA>
Received: from csnet-relay by ti-csl; 1 Mar 86 21:31:40-CST (Sat)
I also disagree strongly with JAR's latest suggestion that EQ? be made
non-essential. Doing so doesn't solve the problem, it just passes the
buck!
I disagree. The point of the agreement that JAR and I reached (I am
the unnamed flamer) was that implementors would have the choice of
having EQ? or a compiler which can split without thinking about the
consequences. The essence of my (and GJS's) position is that if
splitting is allowed, the language has changed to the point we don't
feel comfortable with it anymore. The difference in our positions is
that I'm willing to do away with EQ? as long as if it is implemented
it has the properties that I consider essential. GJS disagrees since
he argues that there is no way to obtain that power if it is not
provided.
When I originally answered JAR's poll, I answered I to the relevant
questions. After rhh sent his message, I revised my position after
thinking about it again. One of the things which I've always liked
about Scheme is the ease with which one can do things like that, which
I believe are intuitive and natural. Adding locations explicitely
into the code just to make EQ? work (as was suggested to me) seems
artificial and no better than emulating closures in languages which
lack them (like C).
∂02-Mar-86 2128 @MC.LCS.MIT.EDU:dfried%indiana.csnet@CSNET-RELAY.ARPA rec
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 2 Mar 86 21:28:47 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 3 Mar 86 00:26:15 EST
Received: from indiana by csnet-relay.csnet id af11085; 2 Mar 86 23:37 EST
Date: Sun, 2 Mar 86 22:59:36 est
From: Dan Friedman <dfried%indiana.csnet@CSNET-RELAY.ARPA>
To: rrrs-authors@mc.lcs.mit.edu
Subject: rec
I do not understand what all the confusion is about.
(rec alpha beta) is a special form which says evaluate
beta in an environment which associates the symbol alpha
with the meaning of beta. This allows for such familiar
expressions (rec ! (lambda (n) (if (zero? n) 1 (* n (! (sub1 n)))))).
This builds a recursive object. We can then associate another
symbol such as fact with this object. Hence we may define fact as
(define fact (rec ! (lambda (n) (if (zero? n) 1 (* n (! (sub1 n))))))).
Now if that were all we could do with rec then I'd just as soon
use the applicative-order Y combinator and be done with it.
However, because rec does not know that beta is a function
we can do fancier things. For example, we can define lazy-cons
(just in the cdr) as
(lazy-cons a b) ==> (rec box
(cons a (lambda ()
(let ([v b])
(set-car! box (lambda () v))
v)))
as a macro. We have created a recursive box. By the time we need
for the box identifier to be bound to the right piece it will be.
As far as I can tell this is what Will was trying to communicate but
it did not seem to be getting through. For those who need reminding
the current marco for rec is
(rec alpha beta) ==> (let ([alpha '*]) (set! alpha beta) alpha)
Dan
∂03-Mar-86 0835 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA EQ?, again
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 3 Mar 86 08:35:00 PST
Received: from GODOT.THINK.COM by MC.LCS.MIT.EDU 3 Mar 86 11:21:36 EST
Received: from guido by GODOT.THINK.COM via CHAOS; Mon, 3 Mar 86 10:50:44 est
Date: Mon, 3 Mar 86 10:52 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: EQ?, again
To: JAR@MC.LCS.MIT.EDU, gls@THINK-AQUINAS.ARPA
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU, gls@THINK-AQUINAS.ARPA
In-Reply-To: <[MC.LCS.MIT.EDU].834417.860228.JAR>
Message-Id: <860303105236.3.GLS@GUIDO.THINK.COM>
Date: Fri, 28 Feb 86 18:26:57 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Date: Fri, 28 Feb 86 16:40 EST
From: Guy Steele <gls at THINK-AQUINAS.ARPA>
Date: Wed, 19 Feb 86 21:37:49 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
I 1. (EQ? (LAMBDA (X) X) (LAMBDA (Y) Y)) ;"Coalescing"
I 2. (EQV? (LAMBDA (X) X) (LAMBDA (Y) Y))
I 3. (LET ((X (LAMBDA (Z) Z))) (EQ? X X)) ;"Splitting"
T 4. (LET ((X (LAMBDA (Z) Z))) (EQV? X X))
I 5. (LET ((X ... any expression evaluating to an exact number ...))
(EQ? X X))
I 6. (EQ? #\X #\X)
It took me a while to figure out how to reconcile your answer to 3 with
your answer to 4. I take it you want procedures to know their identity,
but that you imagine an implementation would still want the liberty to
make (identity-preserving) copies, so EQ? might fail to recognize two
procedures being the same, even though EQV? could succeed?
Sure. Imagine a multiprocessing extension of SCHEME. (Call it, just
for laughs, MULTILISP.) It might be crucial to efficiency to allow
making copies of code for distribution to various processors. I wonder
what Halstead has to say about this.
∂03-Mar-86 0847 @MC.LCS.MIT.EDU:SIG%CARLETON.BITNET@wiscvm.wisc.edu We are using scheme!
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 3 Mar 86 08:46:33 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 3 Mar 86 11:42:26 EST
Received: from wiscvm.wisc.edu by CSNET-RELAY.ARPA id a000814;
3 Mar 86 11:23 EST
Received: from (SIG)CARLETON.BITNET by WISCVM.WISC.EDU on 03/03/86 at
10:19:32 CST
Received: from SIG by CARLETON.BITNET on 03 Mar 86 10:38:31 EST
Date: 03 Mar 86 09:56:45 EST
From: SIG <SIG%CARLETON.BITNET@wiscvm.wisc.edu>
To: Scheme%MIT-MC%csnet-relay@CSNET-RELAY.ARPA
MMDF-Warning: Parse error in original version of preceding line at CSNET-RELAY.ARPA
Subject: We are using scheme!
Hi,
My name is Mike Wilson. I'm working for the Carleton University
School of Computer Science (my job description says "Computer
Scientist" believe it or not). Carleton U. has both TI scheme and
MacScheme, as well as Some flavour of scheme running on the
engineering department vaxen. Scheme is being used for courses at
Carleton at both the undergrad and graduate levels.
Currently, I am working on porting Portable CommonLoops (PCL)
xerox's "common" object-oriented extension to COMMON LISP to run
under TI scheme. In the process of doing this, I've written quite a
large common lisp compatability package (keyworded defun and
defmacro, format, defstruct, etc.). Given the complexity of the
CommonLoops code, I may never get it running completely, but it has
certainly been a useful test of the compatability code.
I must say though, that I would much rather see people doing
scheme compatability packages in common lisp, than the other way
around. In their desparate grasping for efficiency, the common
lisp people have lost *much* of the elegence of lisping.
"If ADA is the PL/1 of the '80s, then COMMON LISP will
be the PL/1 of the '90s!"
∂03-Mar-86 1035 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU rec
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 3 Mar 86 10:35:20 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 3 MAR 86 12:31:00 EST
Date: 3 Mar 1986 10:39 EST (Mon)
Message-ID: <JINX.12187769845.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Dan Friedman <dfried%indiana.csnet@CSNET-RELAY.ARPA>
Cc: rrrs-authors@MC.LCS.MIT.EDU
Subject: rec
In-reply-to: Msg of 2 Mar 1986 22:59-EST from Dan Friedman <dfried%indiana.csnet at CSNET-RELAY.ARPA>
I understand perfectly well what you can do with REC. What I disagree
with is precisely the usage that you are advocating. It is hard to
explain, once your example has been shown, why things like
(rec list-of-as (cons 'a list-of-as))
don't work, and any explanation will seem like a "cop-out". I'd much
rather say that the only essential behavior is when beta is a
lambda-expression, and let individual implementations do whatever they
please.
A similar objection (with which I agree) was raised against internal
DEFINE. The simplest (only?) way to guarantee that a procedure with
internal DEFINEs behaves as if they were all done in parallel is to
disallow anything but procedural DEFINEs internally. While the
implementation may allow for further "fancy" manipulations, requiring
them in the standard only opens a whole new can of worms.
Since I disagree that (rec box
(cons a (lambda ()
(let ([v b])
(set-car! box (lambda () v))
v)))
should work in the standard, I see no difference between REC and
NAMED-LAMBDA.
∂03-Mar-86 1150 @MC.LCS.MIT.EDU:sas@BBN-VAX.ARPA COMMON LISP is the PL/I of LISPs
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 3 Mar 86 11:50:15 PST
Received: from BBN-VAX.ARPA by MC.LCS.MIT.EDU 3 Mar 86 14:33:17 EST
Date: Mon, 3 Mar 86 13:48 EST
From: Seth Steinberg <sas@BBN-VAX.ARPA>
Subject: COMMON LISP is the PL/I of LISPs
To: scheme@mit-mc.ARPA
Actually, I think COMMON LISP will do better than PL/I did as a usable
standard. Personally I think Scheme is the APL of LISPs. It's great
for writing clever, unreadable hacks. Actually, the analogy could go:
1960's APL
1970's PASCAL PL/I
1980's Scheme ADA
1990's COMMON LISP
PASCAL is teleologically similar to Scheme.
Seth
∂03-Mar-86 1223 @MC.LCS.MIT.EDU:KMP@SCRC-STONY-BROOK.ARPA P?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 3 Mar 86 12:23:23 PST
Received: from SCRC-STONY-BROOK.ARPA by MC.LCS.MIT.EDU 3 Mar 86 15:23:50 EST
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 429074; Mon 3-Mar-86 13:31:42-EST
Date: Mon, 3 Mar 86 13:34 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: P?
To: gls@THINK-AQUINAS.ARPA, KMP@SCRC-STONY-BROOK.ARPA
cc: JINX@MIT-AI.ARPA, RRRS-AUTHORS@MIT-MC.ARPA
In-Reply-To: <860303105850.4.GLS@GUIDO.THINK.COM>
Message-ID: <860303133443.5.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Date: Mon, 3 Mar 86 10:58 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Personally, I am content to say that "?" does not get
attached to any predicate which has a root which contains no
alphabetic characters. That is, that ">" is allowed to be a
contraction for "greater?" rather than just "greater", so ">?"
is like saying "greater??". We used a similar reasoning for
not putting "!" on the end of "SET" in T, since "SET!" is
redundant. Any assignment is by definition destructive and
setting an "!" after SET is effectively redundant and just
makes code look ugly. I think the proponents of the name
"SET!" would say that assignments -should- look ugly, and to
that I can only say that I disagree.
I think that SET! should be an assignment primitive, and SET should
construct a set (maybe meaning the same as the Common Lisp REMOVE-DUPLICATES).
This ambiguity about the meaning of "set" in Lisp has always bothered
me, and "!" is the best means of disambiguation I have seen yet.
Anyway, if that was your only concern, I would say you should call set
something else -- BIND, ASSIGN, ATTACH, NAME, or whatever. I guess I
kinda like ASSIGN. There are plenty of names that could be chosen.
The "!" is ugly and inconsistent on SET because it suggests that it is
closely related to the other operators which have "!" in their names.
I don't think it's very closely related since its side-effect occurs a
level up (in 3-lisp style) from the other "!" functions.
I believe that the authors of SETF did us a great disservice by
suggesting that SETF should be able to both assign variables and
modify structures. Anyone who's ever tried to code SETF knows full
well that the variable situation has to be handled by a special
case. That special case is the clue that tells you that something
is wrong in the model which tries to unify the two ideas.
∂03-Mar-86 1227 NET-ORIGIN@MC.LCS.MIT.EDU "splitting" in multiprocessors
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 3 Mar 86 12:27:03 PST
Received: from ASPEN.LCS.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 3 MAR 86 15:24:01 EST
Date: Mon, 3 Mar 86 15:23 EST
From: Robert Halstead <rhh@MIT-VAX.ARPA>
Subject: "splitting" in multiprocessors
To: gls@THINK-AQUINAS.ARPA
cc: JAR@MIT-MC.ARPA, RRRS-AUTHORS@MIT-MC.ARPA
In-Reply-To: <860303105236.3.GLS@GUIDO.THINK.COM>
Message-ID: <860303152359.6.RHH@ASPEN.LCS.MIT.EDU>
Sure. Imagine a multiprocessing extension of SCHEME. (Call it, just
for laughs, MULTILISP.) It might be crucial to efficiency to allow
making copies of code for distribution to various processors. I wonder
what Halstead has to say about this.
Well, currently in Multilisp no "splitting" of procedures is discernible
-- but in part this is due to the fact that the current implementation
doesn't do any local copying of code of the sort you suggest. It is
clear that such copying will be a useful strategy in the future, but I
have always felt that it would be best to think of it as a form of
caching that doesn't affect the naming or identity of objects. In other
words, when a processor would look for a piece of code that it has a
pointer to, it would first consult a CAM or hash table or some such to
see if this is a piece of code of which there is a locally available
copy. This is probably more efficient on a suitably designed processor
than on a plain-vanilla 68020 or 32032, but I guess that doesn't bother
me much.
The motivation for this is that, although it is easy enough to talk
about copying *code*, it is not so easy to make multiple copies of
*environments* or other potentially mutable objects. Since generally
the path to a piece of code will be through an environment (and then a
closure) for which multiple copies are less likely (unless we have
either a low-level snoopy-cache type of protocol or some analysis that
proves particular environments to be immutable), I feel it is better for
environments to contain object references in a system-wide address
space. Processors may then interpret these references differently
according to what selection of information they have cached locally,
rather than having a collection of distinct references to different
copies of objects. If a given object has just one reference (or
"address"), no matter how many copies have been made of the object, then
it is easy for EQ? to operate as though no splitting has occurred. -b.
∂03-Mar-86 1301 @MC.LCS.MIT.EDU:SMC%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU COMMON LISP is the PL/I of LISPs
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 3 Mar 86 13:00:58 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 3 MAR 86 16:00:00 EST
Date: 3 Mar 1986 15:37 EST (Mon)
Message-ID: <SMC.12187824102.BABYL@MIT-OZ>
Sender: SMC%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
From: "Stewart M. Clamen" <SMC%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Seth Steinberg <sas@BBN-VAX.ARPA>
Cc: scheme@MC.LCS.MIT.EDU
Subject: COMMON LISP is the PL/I of LISPs
In-reply-to: Msg of 3 Mar 1986 13:48-EST from Seth Steinberg <sas at BBN-VAX.ARPA>
From: Seth Steinberg <sas at BBN-VAX.ARPA>
To: scheme at mit-mc.ARPA
Re: COMMON LISP is the PL/I of LISPs
Actually, I think COMMON LISP will do better than PL/I did as a usable
standard. Personally I think Scheme is the APL of LISPs. It's great
for writing clever, unreadable hacks. Actually, the analogy could go:
I take exception to that. Unlike APL, Scheme uses the popular set of
characters known as ASCII, which is a superset of the English
characters, and is therefore quite readable. In fact, by definition,
Scheme programs are also trivialy parseable (sic). Take, for example,
this simple procedure (attributable to GJS, I believe):
1 ==> (pp mapcar)
(LAMBDA (F . LISTS)
(IF LISTS
(LET LOOP ((LISTS LISTS))
(LET SCAN
((LISTS LISTS)
(C
(LAMBDA (CARS CDRS) (ACCUMULATOR (APPLY F CARS) (LOOP CDRS)))))
(IF LISTS
(IF (CAR LISTS)
(SCAN
(CDR LISTS)
(LAMBDA (CARS CDRS)
(C (CONS (CAR (CAR LISTS)) CARS)
(CONS (CDR (CAR LISTS)) CDRS))))
INITIAL-VALUE)
(C () ()))))
(ERROR "No arguments to mapping function"
(LIST (LIST MAPPER-GENERATOR ACCUMULATOR INITIAL-VALUE) F))))
SMC
∂03-Mar-86 1521 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA COMMON LISP is the PL/I of LISPs
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 3 Mar 86 15:21:38 PST
Received: from GODOT.THINK.COM by MC.LCS.MIT.EDU 3 Mar 86 17:28:23 EST
Received: from guido by GODOT.THINK.COM via CHAOS; Mon, 3 Mar 86 17:28:05 est
Date: Mon, 3 Mar 86 17:30 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: COMMON LISP is the PL/I of LISPs
To: SMC%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU, sas@BBN-VAX.ARPA
Cc: scheme@MC.LCS.MIT.EDU, gls@THINK-AQUINAS.ARPA
In-Reply-To: <SMC.12187824102.BABYL@MIT-OZ>
Message-Id: <860303173003.7.GLS@GUIDO.THINK.COM>
Date: 3 Mar 1986 15:37 EST (Mon)
From: "Stewart M. Clamen" <SMC%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
From: Seth Steinberg <sas at BBN-VAX.ARPA>
To: scheme at mit-mc.ARPA
Re: COMMON LISP is the PL/I of LISPs
Actually, I think COMMON LISP will do better than PL/I did as a usable
standard. Personally I think Scheme is the APL of LISPs. It's great
for writing clever, unreadable hacks. Actually, the analogy could go:
I take exception to that. Unlike APL, Scheme uses the popular set of
characters known as ASCII, which is a superset of the English
characters, and is therefore quite readable.
I believe that the APL character set is also a superset of "English"
characters, except for not having lower case, which shouldn't matter.
--Guy
∂04-Mar-86 0753 @MC.LCS.MIT.EDU:Jensen%ti-csl.csnet@CSNET-RELAY.ARPA PC Scheme Information
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 4 Mar 86 07:53:30 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 4 Mar 86 10:51:41 EST
Received: from ti-csl by csnet-relay.csnet id ap03450; 4 Mar 86 9:43 EST
Received: by tilde id AA10368; Mon, 3 Mar 86 17:15:45 cst
Date: Mon 3 Mar 86 17:08:22-CST
From: John Jensen <Jensen%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: PC Scheme Information
To: SCHEME%MIT-MC@CSNET-RELAY.ARPA
Message-Id: <12187851592.66.JENSEN@CSL60>
The following information may be of interest to you if you are using
PC Scheme Version 1.0 (18 Nov 85):
1. If you are running on a PC manufactured by a vendor other than
IBM or TI and are unable to execute the EDWIN editor or graphics,
there is a patch available which may correct this problem.
2. If you need to interface PC Scheme to assembly language support
(e.g., to communicate with device drivers), a description of how to
do this is available.
If either of these apply to you, contact me at one of the network
addresses below and I'll send the appropriate description to your network
address.
Regards,
John Jensen
CSNET: JENSEN@TI-CSL
ARPA: JENSEN%TI-CSL@CSNET-RELAY.ARPA
USENET: {ut-sally,convex!smu,texsum}!ti-csl!jensen
-------
∂04-Mar-86 1347 YEKTA@MC.LCS.MIT.EDU PC Scheme Information
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 4 Mar 86 13:45:47 PST
Date: Tue, 4 Mar 86 16:45:27 EST
From: Yekta Gursel <YEKTA@MC.LCS.MIT.EDU>
Subject: PC Scheme Information
To: Jensen%ti-csl.csnet@CSNET-RELAY.ARPA
cc: SCHEME@MC.LCS.MIT.EDU
In-reply-to: Msg of Mon 3 Mar 86 17:08:22-CST from John Jensen <Jensen%ti-csl.csnet at CSNET-RELAY.ARPA>
Message-ID: <[MC.LCS.MIT.EDU].838646.860304.YEKTA>
Could you please send both of these ( 1 and 2 ) to me? There are
a few people around here which is very interested in having those...
Best, --Yekta
∂05-Mar-86 1515 JAR@MC.LCS.MIT.EDU #!null
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 5 Mar 86 15:15:24 PST
Date: Wed, 5 Mar 86 18:15:55 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: #!null
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].840068.860305.JAR>
Is anyone out there particularly enamored of the non-essential feature
#!NULL? I would like to remove it for these reasons:
- It unnecessarily complicates the grammar of <expression>'s and <datum>'s:
- As a <datum>, it is redundant with (), and users will be confused
about when to use it in preference to ().
- As an <expression>, it is redundant with '() and (LIST).
- If it is the same as () for all purposes, and it is implemented,
then we must change the RRRS so that either [a] () is an a legitimate
expression, which it is not either according to consensus or according
to the RRRS; or [b] #!null is NOT a legitimate expression, which
would be inconsistent with the syntactically similar #!true and #!false.
[If #!null is not the same as (), then either the <expression> parser
must differ from the <datum> parser, or implementations must be able to
represents two different empty lists (one which self-evaluates and
another which doesn't).]
If you think that you want the <expression> #!NULL to exist so that
people have a quote-less way to write an expression producing an empty
list, I would argue that there are nicer ways to rewrite '() without
using '. E.g., (LIST). If this is your ONLY reason and you don't like
(LIST), then I would argue to replace the syntax #!NULL with a variable
binding, say NULL or THE-EMPTY-LIST, whose value is an empty list.
∂05-Mar-86 1812 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU #!null
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 5 Mar 86 18:10:11 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 5 MAR 86 20:57:18 EST
Date: Wed, 5 Mar 1986 20:56 EST
Message-ID: <CPH.12188406419.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: #!null
In-reply-to: Msg of 5 Mar 1986 18:15-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
I agree, let's flush it. Another of my ideas, retained despite the
fact that I thought '() quite sufficient. I never use #!null at all.
I guess I'm going to get a bad rep for thinking up crummy ideas and
then not fighting hard enough to make sure they didn't propagate.
∂10-Mar-86 1455 JAR@MC.LCS.MIT.EDU NIHIL EX NIHIL - DON'T SETQ NIL
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 10 Mar 86 13:28:12 PST
Date: Mon, 10 Mar 86 16:28:47 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: NIHIL EX NIHIL - DON'T SETQ NIL
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].845702.860310.JAR>
The RRRS says that the value of the (non-essential) variable NIL should
be the empty list. But I claim that this is not in accordance with
practice, and is ugly besides. My evidence:
1. S&ICP - NIL is used in both ways in the book, but is introduced on
page 17 as being false, and not until page 91 as the empty list. Just
leafing through the book I found many places where nil was used for
false and no places where it was used as empty list.
2. The Art of The Interpreter - I think Steele started using NIL as
false and '() as empty list about the time this paper came out.
3. T - liking Steele's convention, we used it in T source and
documentation starting in 1981 (and I was using it in my Maclisp code
even before that), so it's pretty deeply wired into T "culture" that NIL
is false and NOT the empty list. When The T implementation starts
distinguishing () from #!false, as I hope it will soon, the sources, and
user's code, won't have to change, because this practice has been
followed religiously.
4. Having T and NIL as names for true and false is symmetrical with
having #!true and #!false, especially once #!null goes away (which no
one has complained about, so it will). The manual looks very peculiar
the way it is because T and NIL are described together but have
apparently unrelated purposes.
So unless I hear from someone who has more than about 3 megabytes of
source code making the opposite assumption (that was supposed to be
funny - other arguments will be entertained of course), I'll change the
RRRS to describe NIL as being false, not empty list.
Jonathan
∂12-Mar-86 0325 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: NIHIL EX NIHIL - DON'T SETQ NIL
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 12 Mar 86 03:25:38 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 12 Mar 86 06:26:19 EST
Received: from tektronix by csnet-relay.csnet id ao06699; 12 Mar 86 6:07 EST
Received: by tektronix (5.31/5.14)
id AA16207; Tue, 11 Mar 86 12:43:18 PST
Received: by tekchips (5.31/5.14)
id AA25873; Tue, 11 Mar 86 12:46:16 PST
Message-Id: <8603112046.AA25873@tekchips>
To: JAR@mc.lcs.mit.edu
Cc: RRRS-AUTHORS@mc.lcs.mit.edu,
willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
Subject: Re: NIHIL EX NIHIL - DON'T SETQ NIL
In-Reply-To: Your message of Mon, 10 Mar 86 16:28:47 EST.
<[MC.LCS.MIT.EDU].845702.860310.JAR>
Date: 11 Mar 86 12:46:13 PST (Tue)
From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
An additional argument for making the initial value of NIL be #!false
instead of the empty list: The Second Edition of The Little LISPer
by Dan Friedman and Matthias Felliesen uses NIL as the expression
that evaluates to #!false and () [not '(), unfortunately] as the
expression that evaluates to the empty list. Aside from the use
of square brackets instead of parentheses and the missing quote
before (), the Second Edition looks like straight Scheme to me.
If SRA would market that book right, it would introduce more people
to Scheme than has S&ICP.
In other words: Don't SETQ NIL, (SET! NIL #!FALSE) instead.
Peace, Will
∂12-Mar-86 0339 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA S&I's idea of EQ?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 12 Mar 86 03:38:55 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 12 Mar 86 06:39:35 EST
Received: from tektronix by csnet-relay.csnet id as06699; 12 Mar 86 6:16 EST
Received: by tektronix (5.31/5.14)
id AA16877; Tue, 11 Mar 86 13:03:48 PST
Received: by tekchips (5.31/5.14)
id AA26230; Tue, 11 Mar 86 13:06:47 PST
Message-Id: <8603112106.AA26230@tekchips>
To: RRRS-AUTHORS%MIT-MC%tektronix.csnet@CSNET-RELAY.ARPA
Cc: JAR%MIT-MC%tektronix.csnet@CSNET-RELAY.ARPA,
GJS%MIT-MC%tektronix.csnet@CSNET-RELAY.ARPA
Subject: S&I's idea of EQ?
Date: 11 Mar 86 13:06:43 PST (Tue)
From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
[We've had some trouble with our network phone lines to the East Coast,
so the following may seem out of date.]
I, too, am tired of moving targets and would like to have a stable
definition of Scheme, but I don't think Gerry should be unhappy with
what's going on because the consensus, at least as I perceive it, is
consistent with S&ICP and with the various existing implementations.
As I saw it, the result of the earlier EQ? discussion was a consensus that
(1) it is not an error for EQ? to be called with procedural arguments.
(2) EQ? as used in S&ICP ought to work.
(3) "splitting" was a no-no.
(E.g. (let ((x (lambda () 0))) (eq? x x)) --> #!false is a no-no.)
(4) "coalescing" was ok.
(E.g. (eq? (lambda () 0) (lambda () 0)) --> #!true is ok.)
These points are in decreasing order of consensus, and in particular
the consensus for (4) was not as strong as for (1) through (3). Thus
(4) is still a major topic for discussion.
As I perceived it, Jonathan's poll was primarily intended to determine the
semantics of EQV?, and secondarily to determine the status of (4) above.
So far as I know, nothing in S&ICP will break if EQV? is made
implementation-independent, or if "coalescing" is permitted for EQ?.
Jonathan's insight is that although the semantics of EQ? is hopelessly
implementation-dependent (primarily because of numbers, and secondarily
because of coalescing if coalescing is allowed), it is still possible
to make EQV? implementation-independent even in the presence of coalescing.
The price to be paid is that it would be an error to call EQV? with
procedure arguments -- not "signal an error", but "be an error", so no
one would have to change their implementation.
If we don't allow coalescing for procedures and EQ?, then there is no price
at all. That's why the issue of coalescing for procedures and EQ? is
inseparable from the semantics of EQV?. So far as I can tell, however,
nothing being considered will break S&ICP or force anyone to change their
implementation. If anyone can show me a truly useful piece of existing code
that will break if coalescing is allowed, I'd sure like to see it.
I would hate to have TWO forms for creating procedures. Yes, I dearly wish
that procedure values did not have to be associated with pointers, just as
I dearly wish that numbers did not have to be associated with pointers,
but our earlier discussion convinced me that it is too late to fix either
problem. (In Scheme, that is. I think we can warn designers of new
languages not to make the same mistakes.) What Yale, TI, and Tek want in
Scheme is not the utopia of pointer-free procedures, but sanction for
coalescing.
Why do we want coalescing? It allows optimizing compilers to generate
more efficient code. Examples have been given before, but some people
remain unconvinced so I will repeat one of them. Consider the following
procedure:
(define (foo x) (map (lambda (n) (+ n 3)) x))
If coalescing is not allowed, then a new closure must be created every
time foo is called, and any optimizing compiler that transforms the above
into
(define foo
(let ((bar (lambda (n) (+ n 3))))
(lambda (x) (map bar x))))
is indisputably incorrect. (Unless, of course, the compiler happens to
know the value of map and can prove that map will never be assigned, which
is pretty unlikely in practice.) I think this sort of transformation ought
to be allowed in Scheme, because (1) it makes a fairly big difference in how
fast your programs run; (2) it has been allowed in Scheme historically, so
disallowing it would be a change in the language; for example, Guy Steele's
Rabbit compiler is based on such transformations; and (3) the opponents of
coalescing have yet to give any examples to show why coalescing is bad.
I didn't understand Jonathan's remark to the effect that Common Lisp
requires two different kinds of LAMBDA, one that associates a pointer
and another one that doesn't. I also can't tell from CLtL whether
the optimization illustrated above is supposed to be legal in Common
Lisp. (I assume it is supposed to be legal, but CLtL isn't precise
enough to give much guidance and there is no formal semantics for CL that
I can turn to for answers to such questions.) At any rate, I hardly think
the designers of Common Lisp have devoted more thought to these issues than
we have, so I don't see why we should look to Common Lisp for guidance.
Thanks for hearing me out. Peace, Will
∂13-Mar-86 0437 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@mc.lcs.mit.edu S&I's idea of EQ? (long)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 13 Mar 86 04:37:24 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 13 Mar 86 07:38:04 EST
Received: from tektronix by csnet-relay.csnet id am19748; 13 Mar 86 6:20 EST
Received: from csnet-relay by tektronix.tektronix.CSNET id aw12105;
13 Mar 86 2:27 PST
Received: from mc.lcs.mit.edu by CSNET-RELAY.ARPA id a009197;
12 Mar 86 10:13 EST
Date: 12 Mar 1986 10:11 EST (Wed)
Message-ID: <JINX.12190123993.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@xx.lcs.mit.edu>
To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
Cc: GJS%MIT-MC%tektronix.csnet@CSNET-RELAY.ARPA,
JAR%MIT-MC%tektronix.csnet@CSNET-RELAY.ARPA,
RRRS-AUTHORS%MIT-MC%tektronix.csnet@CSNET-RELAY.ARPA
Subject: S&I's idea of EQ? (long)
In-reply-to: Msg of 11 Mar 1986 16:06-EST from willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
While I think that you are right in assuming that no code written
depends on coalescing not being used, and I understand the position
that being able to coalesce is a desirable goal, your example does not
strike me as particularly good. You claim that an optimizing compiler
will obtain considerably more perfomance out of the coalesced case
than out of the "split" case, but I'm not certain about that:
Clearly if map is known (eg. by the use of declarations, like in
MIT-Scheme), it can be known that eq? (eqv?) is not used on the
procedure values, so coalescing is permitted, but in this case it is
irrelevant since you would want to inline code map into a loop, and
this would hopefully cause the argument to map (the lambda expression)
to be inline coded also, giving you considerably more (time)
efficiency. I think the issue is moot in this case.
If map is not known, the time to look its value up at runtime is
comparable to the time which it takes to close the procedure. In
particular, in MIT-Scheme (because of first class environments, etc),
looking up map can take considerably longer than closing the
lambda-expression, and the latter time is usually negligible. I think
that the small time difference which can be gained in this case is not
very interesting.
It seems from your comment that you are assuming that closing is
inordinately expensive. This is not necessarily so (except
potentially in space). There are 2 implementations of closures I'm
familiar with, and in both cases the above closing can be made very
efficient (in time), although admittedly not as efficient as the
coalesced case, but probably efficient enough:
The "linked environment frame" implementation: Every time a procedure is
applied, a new frame with the arguments is created and the environment
where the body is evaluated is just the "cons" of this new-frame and
the environment where the procedure was closed. To close a lambda
expression, a "cons" is made of its code, and the environment object
("list" of frames) where the lambda expression is evaluated. Thus
closing is just as expensive as a cons.
The "grab what you need" implementation: every time a lambda
expression is "evaluated", the locations of its free variables (or the
values if it can be proven that no assignments occur) are collected
into a closure frame, and the closure is the "cons" of the code
corresponding to the lambda expression and this "closure frame".
Closing in this model is potentially more expensive since variables
may have to be referenced at closing time, and thus a strong desire to
"close eagerly" may occur. In your example, the lambda-expression has
no free variables (except +, but allow me to assume that this is a
known operator), thus closing in this case becomes no more expensive
than a cons. Assume now that it does have free variables as in
(define (foo x) (map (lambda (n) (+ n y)) x))
where y is defined in some outer context.
Then the code can be transformed into
(define foo
(let ((closure-frame (location-of y)))
(lambda (x)
(map (enclose (lambda (n) (+ n y))
closure-frame)
3))))
Where enclose and location-of have the obvious meanings. Again
closing is just as expensive as consing (which is hopefully cheap).
This sort of thing can obviously be extended to more complicated
cases, where the general case would be something like
(define foo
(let ((constant-part (locations-of * + - y w)))
(lambda (x z)
(map (enclose (lambda (n) (* w (+ y (- n z))))
(frame-cons (location-of z) constant-part))
x))))
for
(define (foo x z)
(map (lambda (n) (* w (+ y (- n z)))) x))
So the parts that can be done eagerly are done eagerly, and the others
(plus a cons) are done dynamically. Note that this solution breaks
down if the environment of the lambda-expression is used as a first
class environment, but if this is the case, coalescing is obviously
disallowed also. This intermediate implementation has wider
applicability than coalescing since in the last example the lambda
expression could not trivially be coalesced.
Thus coalescing seems (to me) like a cute little "trick" which may
give you a few instructions (whatever a cons takes) of efficiency in
very limited situations, while a very simple optimization that has no
impact on the semantics gives you most of it in those cases and more
in others.
Again, I understand your position, but it seems that the arguments for
it are not very strong. There is an argument against coalescing which
carries at least as much weight (with me), and has not been presented
before:
Coalescing breaks the environment model of evaluation explained in
S&ICP. This model (which students are shown how to implement in
chapter 4) implies that coalescing is not possible, since a
"different" procedure object is created every time that a lambda
expression is "evaluated". If adherence to this model is important
(which it is to a lot of people involved with teaching S&ICP around
here), coalescing becomes an optimization which can only be used when
the optimizer can prove that the procedures will not be passed to eq?
(eqv?), and not usable by default.
PS: While I don't feel very strongly about it, I think that the
arguments against coalescing should also be heard, expecially since
some of the people who think it is a bad idea are not on the mailing
list, and the ones who are feel that it is unfriendly and refuse to
send messages to it.
∂13-Mar-86 0440 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: S&I's idea of EQ?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 13 Mar 86 04:40:22 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 13 Mar 86 07:38:27 EST
Received: from tektronix by csnet-relay.csnet id ao19748; 13 Mar 86 6:22 EST
Received: from csnet-relay by tektronix.tektronix.CSNET id cr12105;
13 Mar 86 2:59 PST
Received: from ti-csl by csnet-relay.csnet id aa15081; 12 Mar 86 20:32 EST
Received: by tilde id AA17522; Wed, 12 Mar 86 18:40:14 cst
Date: Wed 12 Mar 86 18:28:09-CST
From: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Re: S&I's idea of EQ?
To: willc%tekchips%tektronix@CSNET-RELAY.ARPA,
RRRS-AUTHORS%MIT-MC%tektronix@CSNET-RELAY.ARPA
Cc: JAR%MIT-MC%tektronix@CSNET-RELAY.ARPA,
GJS%MIT-MC%tektronix@CSNET-RELAY.ARPA,
Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
In-Reply-To: <8603112106.AA26230@tekchips>
Message-Id: <12190225414.14.BARTLEY@CSL60>
>From: willc%tekchips@tektronix.CSNET
>
>As I saw it, the result of the earlier EQ? discussion was a consensus that
>
> (1) it is not an error for EQ? to be called with procedural arguments.
> (2) EQ? as used in S&ICP ought to work.
> (3) "splitting" was a no-no.
> (E.g. (let ((x (lambda () 0))) (eq? x x)) --> #!false is a no-no.)
> (4) "coalescing" was ok.
> (E.g. (eq? (lambda () 0) (lambda () 0)) --> #!true is ok.)
>
>These points are in decreasing order of consensus, and in particular
>the consensus for (4) was not as strong as for (1) through (3). Thus
>(4) is still a major topic for discussion.
I've been too preoccupied with other things to give this debate the
attention it deserves, but I feel somewhat uncomfortable with this
declaration of a consensus, even though I am largely in agreement with
Will's sentiments.
My concern is that splitting can occur in suprising places in an
optimizing compiler, and that more than just LAMBDA expressions are
involved. Is there a consensus on coalescing and splitting for
bignums and reals? Prohibiting splitting seems to be equivalent to
prohibiting constant propagation (beta substitution).
Regards,
David Bartley
-------
∂13-Mar-86 0754 @MC.LCS.MIT.EDU:harrison@nrl-aic mailing list
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 13 Mar 86 07:54:17 PST
Received: from nrl-aic by MC.LCS.MIT.EDU 13 Mar 86 10:54:22 EST
Date: Thu, 13 Mar 86 10:53:09 est
From: Patrick Harrison <harrison@nrl-aic>
Message-Id: <8603131553.AA12034@nrl-aic>
To: scheme@MIT-MC
Subject: mailing list
Please put me on the mailing list. We are using SCHEME for
testing concepts for a larger project being conducted in the
Multi-sensor Integration area. Two students at the U.S. Naval
are currently using the object oriented package in SCHEME to
implement a small subset of this problem.
Pat Harrison <harrison@aic.ARPA>
∂13-Mar-86 0859 @MC.LCS.MIT.EDU:harrison@nrl-aic corrected address
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 13 Mar 86 08:59:37 PST
Received: from nrl-aic by MC.LCS.MIT.EDU 13 Mar 86 10:56:34 EST
Date: Thu, 13 Mar 86 10:54:39 est
From: Patrick Harrison <harrison@nrl-aic>
Message-Id: <8603131554.AA12040@nrl-aic>
To: scheme@MIT-MC
Subject: corrected address
Reference mailing list, my address <harrison@nrl-aic.ARPA
Pat Harrison
∂13-Mar-86 1404 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: S&I's idea of EQ? (long)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 13 Mar 86 14:04:34 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 13 Mar 86 16:41:45 EST
Received: from indiana by csnet-relay.csnet id af25787; 13 Mar 86 16:20 EST
Date: Thu, 13 Mar 86 15:37:09 est
From: Kent Dybvig <dyb@indiana>
To: JINX@OZ.AI.MIT.EDU
Subject: Re: S&I's idea of EQ? (long)
Cc: rrrs-authors@mit-mc
The cost of closing in the very case you describe is indeed large
in Chez Scheme, as in most later Scheme systems. Compared with other
costs, the cost of allocation in general is quite high. Allocation
incurs several direct and indirect costs including (1) the several
instructions to do the allocation, (2) the potential for page faults,
and ultimately (3) garbage collection overhead. By comparison, all
identifier lookups, whether global, local, or through the closure,
are one instruction (more correctly, one operand of an instruction).
Function call is only a few instructions after pushing the arguments.
Very little allocation is performed by the system, and that is why it
ends up being so fast. In fact, the only things ever allocated are
closures for lambda expressions that are not directly invoked, boxes
for assigned identifiers, and stack objects for continuations. Many
programs do no allocation at all and most do little outside explicit
calls to cons and the like.
Chez Scheme always returns the same closure for a lambda with no free
variables, thereby avoiding even the cost of a cons. When this closure
occurs in a loop, the savings in page faults alone is significant.
However, I do not feel that this emphasis on speed is more important
than emphasis on functionality. In light of the discussion about using
closures as abstract objects and what I feel to be cleanest, my belated
answer to Jonathan's EQ-Quiz is as follows (no coalescing, no splitting):
T (eq? (lambda (x) x) (lambda (y) y))
T (eqv? (lambda (x) x) (lambda (y) y))
T (let ((x (lambda (z) z))) (eq? x x))
T (let ((x (lambda (z) z))) (eqv? x x))
T (let ((x ... any expression evaluating to an exact number ...))
(eq? x x))
I (eq? #\x #\x)
I am all in favor of having switches in the system that trade functionality
(flexibility, anyway) for speed, as long as the users knows pretty much
what's going on. The user can decide if the extra speed is worth the price.
And, as you point out, it is perfectly valid even in the absense of such
a switch for the compiler to do anything it cannot be caught at, including
coalescing or splitting objects.
If anyone cares, I can write a less coherent response related to EQ on
non Von-Neumann architectures, such as the cellular computer of Mago,
where pointers do not exist. (The earlier remarks about MultiLisp are
relevant only to large-grain architecture, which are essentially parallel
variants of the Von-Neumann architecture.) My ideas for EQ along these
lines are not completely formed but relate to immedidate (pointer-encoded)
objects also.
Question: On a machine supporting virtual memory, If EQ is based on the
(virtual) address, what if two pieces of the virtual address space are
mapped to the same physical address?
∂13-Mar-86 1424 JAR@MC.LCS.MIT.EDU survey results (long message)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 13 Mar 86 14:23:49 PST
Date: Thu, 13 Mar 86 17:24:24 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: survey results (long message)
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].849840.860313.JAR>
Here's a summary of the 16 completed surveys I received:
1. (EQ? (LAMBDA (X) X) (LAMBDA (Y) Y))
14 - I, 2 - F
Winner: I
This question, which I think is what the recent Bartley/JINX debate has
been about, was the only one on which there seemed to be consensus.
Everyone except Sussman and Halstead said that the result should be
implementation-dependent but not an error. (Maybe JINX wants to change
his vote now?) The dissenters definitely wanted the answer to be false.
I interpret the dissenting view as follows: evaluation of a
LAMBDA-expression MUST be a side-effect; a denotational semantics MUST
have locations associated with procedures; we must change existing
implementations (like T, and maybe TI's compilers); we must change the
RRRS, which is mute on this point; and Scheme must differ from Common
Lisp here.
My editorial opinion: Scheme should be compatible with the published
RRRS, with Common Lisp, with the majority, and with its current
implementations. People who teach from S&I might want to note that some
scheme and CL implementations perform "coalescing" optimizations.
2. (EQV? (LAMBDA (X) X) (LAMBDA (Y) Y))
8 - I, 7 - E, 1 - F.
Winner: I
Half the respondents want EQV? to have the same implementation-dependent
behavior as EQ?. The other half want EQV? to be defined in an
implementation-independent way.
Given the lack of consensus for change, I would again suggest the
conservative stance of leaving things as they are, compatible with the
RRRS and with Common Lisp's EQL. I would be happy, however, if someone
continued this crusade and managed to convince all those people who want
an ugly EQV? that they're wrong.
3. (LET ((P (LAMBDA (X) X))) (EQ? P P))
9 - I, 6 - T, 1 - U.
Winner: T
Half want particular evaluations of lambda-expressions to "have
identity," thus again requiring a more complicated semantics involving
locations, and forbidding indiscriminate beta-conversion. The other
half want simpler semantics, and the conceptual improvements and
implementation freedom which result. (Please pardon my biased
interpretation, it's supposed to be mildly humorous.)
Again, there's no consensus, so I would recommend staying with the RRRS
and Common Lisp status quo, even though it's a "minority" position
(among those who turned in surveys) and in opposition to mine.
4. (LET ((P (LAMBDA (X) X))) (EQV? P P))
5 - T, 7 - E, 3 - I, 1 - U.
Winner: T
This was asking, among other things, whether the semantics of Scheme
needed to associate locations with procedures, even if EQ? were excised.
To be consistent with everything else, especially question number 2, I'd
say again we'd have to stick with the status quo.
5. (LET ((N <number>)) (EQ? N N))
5 - T, 9 - I, 1 - E, 1 - U.
Winner: I
Hard to interpret these results. One issue that hasn't been raised is
that Common Lisp and RRRS disagree on this question; RRRS says that the
answer should be T, and Common Lisp says I (implementation-dependent -
numbers don't "have identity", can be "copied freely"). I think that
Sussman says that he and S&I don't care about numbers having identity,
and wonders why anyone would really care. This topic might need more
discussion; e.g. one could use my argument (previously advanced to an
opposite end) that procedures and numbers shouldn't be treated
differently, with the conclusion this time that since procedures "have
identity", so should numbers.
Given that Scheme's EQ? is otherwise so close to Common Lisp's EQ, and
that a majority want to change scheme to be compatible with CL, it would
be a shame for them to disagree here, so I would be inclined to change
the report. E.g. the way it is, it will be quite difficult to embed
scheme implementations in common lisp, and vice versa. Note that this
change in the language definition would not require anyone's
implementation to change, although it might require some people's
programs to change (speak up if this is the case!).
6. (EQ? #\X #\X)
7 - I, 2 - T, 7 - X
Winner: I
I saw this question as asking more or less whether characters should be
"interned". I think the consensus is that they don't need to be. That
would be consistent with the RRRS and with Common Lisp.
[One respondent originally answered E on the grounds that characters
shouldn't be expressions, so this would be a syntax error; but I think
the consensus on that question is that characters SHOULD self-evaluate.]
----------
I guess I mounted this failed little crusade for pure location-less
procedures in an attempt to make Scheme have cleaner, more abstract
semantics, with the implication that this would have many practical
benefits. I do believe that having a way to denote pure objects
(behaviors) would have far-reaching consequences. But maybe Scheme is
an inapprioriate vehicle for this kind of progress; the "ideal
programming language" would probably differ from Scheme in many other
ways as well.
My advice to the Yale and TI efforts, which seem to agree with me on the
need for location-less procedures, is to implement both kinds of
procedures, and support two different dialects (or two different LAMBDA
special forms). I know that the "native" T dialect already has to be
incompatible with Scheme in various ways (its DEFINE and WRITE and a few
other things differ incompatibly), and that semantically, at least,
impure procedures can be simulated in T by pure ones, so this is
probably not such a big deal - maybe involving a flag in the compiler's
LAMBDA-nodes, or maybe something more general. I hope other people who
want to work on issues like this one which involve incompatibility with
Scheme will come up with similar solutions, implementing both crufty,
backwards Scheme AND the wonderful language of their choice, and not
give up on either line of work.
I'll try to come up with an objective, concise summary of this EQ?
debate to include in the next edition of the report.
Jonathan
∂13-Mar-86 1453 @MC.LCS.MIT.EDU:rjk@mitre-bedford.ARPA Unexpected Message
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 13 Mar 86 14:50:45 PST
Received: from mitre-bedford.ARPA by MC.LCS.MIT.EDU 13 Mar 86 15:40:54 EST
Date: Thu, 13 Mar 86 14:03:25 est
From: rjk@mitre-bedford.ARPA (Ruben J. Kleiman)
Full-Name: Ruben J. Kleiman
Message-Id: <8603131903.AA04584@mitre-bedford.ARPA>
Organization: The MITRE Corp., Bedford, MA
To: scheme@MIT-MC.ARPA
Subject: Unexpected Message
I received the following message addressed to you:
From daemon Thu Mar 13 13:17:37 1986
Received: from nrl-aic by MC.LCS.MIT.EDU 13 Mar 86 10:56:34 EST
Date: Thu, 13 Mar 86 10:54:39 est
From: Patrick Harrison <harrison@nrl-aic.ARPA>
Message-Id: <8603131554.AA12040@nrl-aic>
To: scheme@MIT-MC.ARPA
Subject: corrected address
Reference mailing list, my address <harrison@nrl-aic.ARPA
Pat Harrison
Are the daemons becoming demonical, or something?
- R
∂13-Mar-86 1508 JAR@MC.LCS.MIT.EDU S&I's idea of EQ?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 13 Mar 86 15:07:58 PST
Date: Thu, 13 Mar 86 18:08:36 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: S&I's idea of EQ?
To: dyb%indiana@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU, JINX@OZ.AI.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].849893.860313.JAR>
What would you want the following to return?
(eq? (lambda (x) (let ((y x)) y))
(lambda (z) (let ((w (lambda () z))) (w))))
∂13-Mar-86 1546 JAR@MC.LCS.MIT.EDU S&I's idea of EQ?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 13 Mar 86 15:45:56 PST
Date: Thu, 13 Mar 86 18:46:39 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: S&I's idea of EQ?
To: JINX@OZ.AI.MIT.EDU
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of 12 Mar 1986 10:11 EST (Wed) from Bill Rozas <JINX%OZ.AI.MIT.EDU at xx.lcs.mit.edu>
Message-ID: <[MC.LCS.MIT.EDU].849914.860313.JAR>
Date: 12 Mar 1986 10:11 EST (Wed)
From: Bill Rozas <JINX%OZ.AI.MIT.EDU at xx.lcs.mit.edu>
If map is not known, the time to look its value up at runtime is
comparable to the time which it takes to close the procedure. In
particular, in MIT-Scheme (because of first class environments, etc),
looking up map can take considerably longer than closing the
lambda-expression, and the latter time is usually negligible. I think
that the small time difference which can be gained in this case is not
very interesting.
This is an empirical question for which I don't have any data, but my
intuition is that the way procedures are used and implemented in T, the
consing overhead here would be unacceptable, probably high enough to
make T want to be incompatible with Scheme in yet one more way, if
Scheme were changed. The fact that the T implementation "coalesces"
procedures is exploited very heavily in the implementation and, I
suspect, in the way some users write code. Not all Scheme
implementations have MIT scheme's high variable lookup overhead; consing
and space are not as cheap in most implementations as in MIT scheme; and
not all compilers or users choose to do as much analysis and procedure
integration as you believe is appropriate.
∂13-Mar-86 1615 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU S&I's idea of EQ?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 13 Mar 86 16:15:29 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 13 MAR 86 19:15:36 EST
Date: 13 Mar 1986 19:15 EST (Thu)
Message-ID: <JINX.12190485322.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: S&I's idea of EQ?
In-reply-to: Msg of 13 Mar 1986 18:46-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
I agree that the advantages of coalescing are implementation
dependent, but that is part of what I tried to point out in my
message: closures can be implemented in such a way that it is not so
clear that coalescing is necessary. The reason some implementations
want to coalesce is precisely because closing is too expensive for
them (BTW, what's the difference between C and Scheme if closures are
so expensive that users avoid them like the plague?). Note that the
optimization I suggested does not imply a high variable lookup cost, its
only added cost is the "cons", but it is more applicable than
coalescing and satisfies the procedures-have-locations semantics.
Besides, coalescing is not really necessary, since it is an
optimization which can be trivially accomplished by the user by
slightly rearranging his/her code. On the other hand, if the
implementation is free to coalesce, the other behaviour can only be
obtained thorugh very obscure and unintuitive coding. I'm not saying
that I agree completely with the philosophy that if an optimization
can be done by the user himself the implementation should not do it,
but it is something worth considering.
Again, I don't care that much, but I have not seen powerful reasons to
make the decision go that way.
∂14-Mar-86 0311 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: S&I's idea of EQ? (long)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 14 Mar 86 03:09:47 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 14 Mar 86 06:10:23 EST
Received: from tektronix by csnet-relay.csnet id a003806; 14 Mar 86 5:57 EST
Received: from csnet-relay by tektronix.tektronix.CSNET id as23113;
14 Mar 86 2:23 PST
Received: from ti-csl by csnet-relay.csnet id aa23215; 13 Mar 86 12:33 EST
Received: by tilde id AA05556; Thu, 13 Mar 86 10:05:18 cst
Date: Thu 13 Mar 86 09:57:21-CST
From: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Re: S&I's idea of EQ? (long)
To: JINX%OZ.AI.MIT.EDU%xx.lcs.mit.edu@CSNET-RELAY.ARPA,
willc%tekchips%tektronix@CSNET-RELAY.ARPA
Cc: GJS%MIT-MC%tektronix@CSNET-RELAY.ARPA,
JAR%MIT-MC%tektronix <@CSNET-RELAY.ARPA:JAR%MIT-MC%tektronix@csnet-relrrs-author-mc%tektronix>,
Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
In-Reply-To: <JINX.12190123993.BABYL@MIT-OZ>
Message-Id: <12190394569.68.BARTLEY@CSL60>
JINX's analysis is valid, but I disagree with the conclusion that
since closures are (roughly) ``no more expensive than conses'' that
they are not worth optimizing. It is easy to construct examples of
``inner loops'' in which such consing dominates the execution time.
I've investigated these optimizations precisely because of my
experience with real programs that needed such help.
One such program worked exclusively with numbers we are able to
represent as immediates (no number consing), yet mystified its author
because of occasional GCs. (The GCs were unexpected because the
generated code managed to allocate all variables to registers,
avoiding use of the heap.) We'll never supplant Pascal that way!
My goal is to develop implementations of Scheme that rival other
languages in performance without sacrificing those things that make
Scheme so desirable a language in the first place. In this case, I
feel that the balance tips in favor of allowing useful optimizations
to take place.
It seems that any final decision on this point will come down to
trading off potential performance for certain semantic ideals. I
guess I'm as unconvinced by some of the arguments against coalescing
as others are by my concerns about performance!
Regards,
David Bartley
-------
∂14-Mar-86 0937 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: S&I's idea of EQ?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 14 Mar 86 09:37:30 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 14 Mar 86 12:37:52 EST
Received: from ti-csl by csnet-relay.csnet id aa06829; 14 Mar 86 11:48 EST
Received: by tilde id AA08235; Fri, 14 Mar 86 09:40:12 cst
Date: Fri 14 Mar 86 09:27:17-CST
From: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Re: S&I's idea of EQ?
To: JINX%OZ.AI.MIT.EDU%XX.LCS.MIT.EDU@CSNET-RELAY.ARPA,
JAR%MC.LCS.MIT.EDU@CSNET-RELAY.ARPA
Cc: RRRS-AUTHORS%MC.LCS.MIT.EDU@CSNET-RELAY.ARPA,
Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
In-Reply-To: <JINX.12190485322.BABYL@MIT-OZ>
Message-Id: <12190651239.68.BARTLEY@CSL60>
From JINX:
> Besides, coalescing is not really necessary, since it is an
> optimization which can be trivially accomplished by the user by
> slightly rearranging his/her code. On the other hand, if the
> implementation is free to coalesce, the other behaviour can only be
> obtained thorugh very obscure and unintuitive coding. I'm not saying
> that I agree completely with the philosophy that if an optimization
> can be done by the user himself the implementation should not do it,
> but it is something worth considering.
I would agree with your first sentence except for three problems:
(1) Not all programmers have been properly trained in good programming
style using Scheme. Let's hope this improves drastically with time,
but I'm constantly amazed at the influence of styles from other Lisp
dialects, Pascal, and even FORTRAN on Scheme programmers I've run into!
(2) Many Scheme systems implement most of the ``special forms'' in
RRRS as well as other syntactic extensions as macros. One reason for
optimization is to overcome the mish-mash that often results from
macro expansion. For example, the programmer who uses DO doesn't have
the option of placing the LAMBDA which results in the best possible
place in the overall program.
(3) Similarly, Scheme programs that are created by other programs
often can be substantially improved by an optimizing compiler.
> that I agree completely with the philosophy that if an optimization
> can be done by the user himself the implementation should not do it,
> but it is something worth considering.
So, I think it's irrelevant whether an implementation should do an
optimization that the users can do themselves, since they frequently
can't.
Regards,
David Bartley
-------
∂14-Mar-86 1218 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: S&I's idea of EQ? (OOPS!)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 14 Mar 86 12:18:33 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 14 Mar 86 15:18:27 EST
Received: from indiana by csnet-relay.csnet id a008939; 14 Mar 86 15:03 EST
Date: Fri, 14 Mar 86 12:56:33 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: JAR@mc.lcs.mit.edu
Subject: Re: S&I's idea of EQ? (OOPS!)
Cc: JINX@oz.ai.mit.edu, RRRS-AUTHORS@mc.lcs.mit.edu
Yes, I see what you mean. Here is my real answer to the EQ-Quiz.
Sorry for the slip up... I went back to edit lower case t's and
f's (because lower case i didn't look right) into upper case T's
and F's and apparently screwed up.
F (eq? (lambda (x) x) (lambda (y) y))
F (eqv? (lambda (x) x) (lambda (y) y))
T (let ((x (lambda (z) z))) (eq? x x))
T (let ((x (lambda (z) z))) (eqv? x x))
T (let ((x ... any expression evaluating to an exact number ...))
(eq? x x))
I (eq? #\x #\x)
There is one important one to add, by the way:
F (let ([f (lambda () (lambda (y) y))]) (eq? (f) (f)))
Which right now returns true in Chez Scheme. Sigh...
Kent
∂17-Mar-86 1644 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: S&I's idea of EQ?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 17 Mar 86 16:44:13 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 17 Mar 86 19:44:39 EST
Received: from tektronix by csnet-relay.csnet id av06092; 17 Mar 86 19:04 EST
Received: by tektronix (5.31/5.14)
id AA15558; Mon, 17 Mar 86 13:27:56 PST
Received: by tekchips (5.31/5.14)
id AA08962; Mon, 17 Mar 86 13:30:45 PST
Message-Id: <8603172130.AA08962@tekchips>
To: RRRS-AUTHORS%MIT-MC%tektronix.csnet@CSNET-RELAY.ARPA
Subject: Re: S&I's idea of EQ?
Date: 17 Mar 86 13:30:37 PST (Mon)
From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
Rozas is correct that closing a lambda expression can be as cheap as
consing, and that the closure may not be necessary if the procedure
receiving it is known to the compiler. (My example wasn't very good
for another reason as well, namely that the map procedure is going
to cons anyway.)
That's not to say that closing a lambda expression is as cheap as a
variable reference. Consider an 8 MHz 68000 without wait states.
Assuming a stop and copy garbage collector that can traverse and copy
1 megabyte of live storage in 5 seconds, a heap at equilibrium, and a
50% load factor, it takes 5 microseconds to reclaim each byte of storage.
Hence a cons would take 40 microseconds in gc time alone. In interpreted
Scheme 312 consing or closing takes an additional 30 microseconds in the
storage allocator; compiling would reduce that to 20 microseconds.
Overall that's 70 microseconds in interpreted code, 60 in compiled code.
A variable reference takes 12 to 30 microseconds in interpreted Scheme
312, and would take .5 to 6 microseconds in compiled code. Thus
variable references in compiled code are an order of magnitude faster
than closing a lambda expression.
You can reduce the storage allocation and gc time by using a more
sophisticated garbage collector, but if you're going to go to the
trouble of doing that then you're probably going to use an optimizing
compiler and the average variable reference should be closer to 1
microsecond than to 6 microseconds.
If variable references are slow in MIT Scheme, I suspect the problem
lies not with environments as first class objects but with the fact
that MIT Scheme allows the environment structure to be side effected
by internal definitions that do not appear at the head of the lambda
body in which they appear. It appears to me that the authors of S&ICP
considered such side effects to be an MIT extension to Scheme that
other implementations do not have to support; the relevant footnotes
are in chapter 1, footnote 23, page 28; in chapter 5, footnote 21, page
440; in chapter 5, footnote 40, page 487; in chapter 5, footnote 42,
page 490.
One of the problems with using an operational definition such as a
meta-circular interpreter to specify the semantics of a programming
language is that it is never clear whether a feature is incidental to
that particular interpreter or a universal feature that must be
supported by all interpreters. It is clear, for example, that
the interpreter in chapter 4 of S&ICP creates a new closure every
time it encounters a lambda expression, but it is equally clear that
if you take the car of such a closure you get the symbol PROCEDURE.
That's why I prefer a denotational semantics.
Peace, Will
∂17-Mar-86 1840 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU S&I's idea of EQ?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 17 Mar 86 18:40:03 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 17 MAR 86 21:26:58 EST
Date: 17 Mar 1986 21:18 EST (Mon)
Message-ID: <JINX.12191556290.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
cc: rrrs-authors@MC.LCS.MIT.EDU
Subject: S&I's idea of EQ?
In-reply-to: Msg of 17 Mar 1986 16:30-EST from willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
I disagree that an "optimizing" garbage collector implies an
"optimizing" compiler. We have one, but not the other to the same
degree. The former is considerably easier to write since it is a much
smaller program.
By first class environments I do not mean that they can be passed
around, but that they can be manipulated. What's the use if they can
only be passed around? Clearly it is incremental definition that
causes the problem, but I consider them an essential feature of first
class environments.
A cons in MIT-Scheme consists of 4 (move) instructions in compiled
code (without garbage collection). A variable reference consists of 1
to 2 in most cases (the largest exception is when they must be left to
the interpreter, because of potential incremental definitions, and
this occurs rarely in compiled code).
It seems to me that the extra performance is not worth the effort,
since it makes the language at lot harder to use because it puts the
user at the mercy of the compiler. I believe that a declaration
allowing the optimization is appropriate since then any confusion
would be caused by the user, not by the compiler doing something
unexpected.
Again, I believe that this optimization can be obtained by the user
almost all of the time. I don't accept the argument that users do not
have control over macro expansion, or over imbedded languages. They
certainly do not have control, but the macro writer or "imbedder" does
and should be careful about the code being generated in the same way
that a compiler writer must be careful about using registers. A
declaration would help here too since the macro could expand into code
that contained it by default. Supposedly the user of the macro could
not use any "hidden" lambdas since he would not know the
implementation of the macro.
I am not necessarily advocating for operational semantics, but once we
have accepted that there is no splitting, it seems that the only
consistent model left is the one that requires every "evaluation" of a
lambda expression to be consed. And this means no coalescing in the
absence of declarations or proof. Either procedures have associated
locations or they do not.
I think that this "solution" of allowing coalescing but not splitting
is the worst of both worlds since it breaks both models. It will
probably not confuse me (although it might), but I think it would
confuse a naive user.
PS: How come people object to the declaration allowing the
optimization? It seems inocuous to me and would give everybody what
they wanted. Given that the semantics are no longer "clean" since
splitting is not allowed, we may as well be consistent.
Note that some implementations could advertise that the
optimization was on by default, and the other behaviour could be
obtained by a "negative" declaration.
∂18-Mar-86 2105 @MC.LCS.MIT.EDU:hsc8r120006%uhcl.csnet@CSNET-RELAY.ARPA scheme community
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 18 Mar 86 21:04:59 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 19 Mar 86 00:04:23 EST
Received: from uhcl by csnet-relay.csnet id aa21067; 18 Mar 86 23:35 EST
Date: Tue, 18 Mar 86 15:35 CST
From: "Dede.Chris" <hsc8r120006%uhcl.csnet@CSNET-RELAY.ARPA>
To: scheme@mc.lcs.mit.edu
cc: dede%uhcl.csnet@CSNET-RELAY.ARPA
Subject: scheme community
I am hoping eventually to be able to offer a SCHEME course at my university
and am interested in sharing ideas about instructional materials. Would
like to be involved in the information exchange--what do I need to do?
--Chris Dede
∂19-Mar-86 1648 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: S&I's idea of EQ?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 19 Mar 86 16:46:45 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 19 Mar 86 19:47:25 EST
Received: from tektronix by csnet-relay.csnet id ag01727; 19 Mar 86 18:47 EST
Received: by tektronix (5.31/5.14)
id AA17743; Wed, 19 Mar 86 12:37:42 PST
Received: by tekchips (5.31/5.14)
id AA15513; Wed, 19 Mar 86 12:40:20 PST
Message-Id: <8603192040.AA15513@tekchips>
To: RRRS-AUTHORS%MIT-MC%tektronix.csnet@CSNET-RELAY.ARPA,
JINX%OZ.AI.MIT.EDU@xx.lcs.mit.edu
Subject: Re: S&I's idea of EQ?
In-Reply-To: Your message of 17 Mar 1986 21:18 EST (Mon).
<JINX.12191556290.BABYL@MIT-OZ>
Date: 19 Mar 86 12:40:12 PST (Wed)
From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
JINX's messages have helped, but I still do not understand three of
his points:
> By first class environments I do not mean that they can be passed
> around, but that they can be manipulated. What's the use if they can
> only be passed around?
As numbers demonstrate, it is both possible and useful to manipulate
objects without side effecting them. As I recall, S&ICP uses only
the make-environment and eval operations on environments, neither of
which mutates an environment. I can imagine many other
non-side-effecting operations on environments, such as:
(lookup env id)
(extend env1 env2)
(bind-to-fresh-location env id)
(hide env id)
Someone might want to argue that these operations would be more useful
if they had an exclamation point in their names, but it would take a
real argument; the non-side-effecting versions shouldn't be dismissed
out of hand.
> A cons in MIT-Scheme consists of 4 (move) instructions in compiled
> code (without garbage collection).
It would be wonderful if compiled code could be made to run without
garbage collection. As Kent Dybvig, David Bartley, and I have pointed
out, a cons is usually more expensive in gc time than in allocation time.
When last I heard, MIT Scheme on the HP 9836 was using a simple stop and
copy collector with essentially the same performance as the one in Scheme
312--that is, on a 12 MHz 68000 without wait states the garbage collector
will run for 3 to 4 seconds per megabyte of live storage. If the heap is
at equilibrium (i.e., storage is being dropped as fast as it is being
allocated) and the active semispace is half full, then the cost of
allocating 8 bytes of storage cannot be less than 24 to 32 microseconds,
no matter how few instructions are used to allocate the storage. It
follows that if a variable reference takes 1 microsecond, then creating
a closure is about 25 times as expensive as a variable reference. If
the active semispace is 75% full, then creating a closure is 75 times
as expensive as a variable reference.
The HP 9836 does not support virtual memory. Caching or paging would
make consing significantly more expensive than the above calculations
indicate.
The only way to escape from these calculations is to use a more
sophisticated garbage collection algorithm such as the Hewitt-Lieberman
algorithm (or its little brother, generation scavenging). The worst case
behavior of these algorithms appears to be slightly worse than that of
straight stop and copy, so it is an empirical question how they will
behave in a real Lisp environment. The only data that I have seen appears
in a 1984 paper by David Moon; he found that the cost of consing was
reduced but remained very significant. Clearly there is still a shortage
of good data. If MIT Scheme has changed to use a more sophisticated
collector, then I hope someone will post numbers characterizing its
performance.
> ...once we
> have accepted that there is no splitting, it seems that the only
> consistent model left is the one that requires every "evaluation" of a
> lambda expression to be consed....Either procedures have associated
> locations or they do not.
A few months ago I proposed the following consistent semantics: if eq?
is given procedures as arguments, it returns #!true if the associated
locations are the same. If the associated locations are different but
the "functional parts" (E* --> K --> C) are equal, then eq? may return
#!true or #!false at its whim. If the functional parts are not equal,
then eq? must return #!false.
Whether the functional parts are equal is of course noncomputable, but
a semantics doesn't have to be computable. The fact that eq? can just
return #!false if the associated locations are unequal proves the
existence of a model for this semantics. The possibility of coalescing
optimizations as performed by compilers like Rabbit and the T3 compiler
prove the existence of other interesting and useful models for this
semantics.
Peace, Will
∂20-Mar-86 0334 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@mc.lcs.mit.edu S&I's idea of EQ?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 20 Mar 86 03:34:42 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 20 Mar 86 06:33:09 EST
Received: from tektronix by csnet-relay.csnet id ab07364; 20 Mar 86 5:57 EST
Received: from csnet-relay by tektronix.tektronix.CSNET id bu05707;
20 Mar 86 2:39 PST
Received: from mc.lcs.mit.edu by CSNET-RELAY.ARPA id a003476;
19 Mar 86 22:07 EST
Date: 19 Mar 1986 22:04 EST (Wed)
Message-ID: <JINX.12192088922.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@xx.lcs.mit.edu>
To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
Cc: JINX%OZ.AI.MIT.EDU@xx.lcs.mit.edu,
RRRS-AUTHORS%MIT-MC%tektronix.csnet@CSNET-RELAY.ARPA
Subject: S&I's idea of EQ?
In-reply-to: Msg of 19 Mar 1986 15:40-EST from willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
As numbers demonstrate, it is both possible and useful to manipulate
objects without side effecting them. As I recall, S&ICP uses only
the make-environment and eval operations on environments, neither of
which mutates an environment. I can imagine many other
non-side-effecting operations on environments, such as:
What happens to (eval '(define x 4) <some-environment>)?
When last I heard, MIT Scheme on the HP 9836 was using a simple stop and
copy collector
MIT Scheme uses a somewhat modified stop and copy garbage collector
which originally increased performance significantly. I have no
current figures. On average code (compiled or not) the overhead
caused by the garbage collector is at worst 10% (% of time spent
garbage collecting vs. total time). I feel that this is completely
acceptable. Some of us (GJS in particular) don't believe very much on
optimizing consing, but rather in (very) large memories and very fast
garbage collectors.
A few months ago I proposed the following consistent semantics: if eq?
is given procedures as arguments, it returns #!true if the associated
locations are the same. If the associated locations are different but
the "functional parts" (E* --> K --> C) are equal, then eq? may return
#!true or #!false at its whim. If the functional parts are not equal,
then eq? must return #!false.
I'm not sure a I understand your domain equation, and I may be missing
something, but...
1) Do you mean that an implementation might choose always to return
#!true on 2 different "closings" of the same lambda expression?
If so, I consider this proposal unacceptable since 2 different
invocations of
(define (make-cell contents)
(define (setter new-value)
(set! contents new-value))
(lambda (message)
(cond ((eq? message 'CONTENTS) contents)
((eq? message 'SET-CONTENTS!) setter)
(else (error "Cell: Unknown request"))))))
would result in EQ? objects which are clearly distinguishable by other means.
2) I'm confused by your proposal. I think naive users would be
confused also. If models become too complicated, the language becomes
intractable. If the mathematics of the intuitively simple model are
less elegant, that may imply that the mathematic representation is not
adequate. In case of conflict, I will usually choose the intuitively
simple model since a new representation better suited to it may appear
tomorrow. One of the main reasons why Scheme has become popular (I
think) is that it is easy to learn. This proposal would complicate it
unnecessarily.
∂21-Mar-86 0320 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: S&I's idea of EQ?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 21 Mar 86 03:20:00 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 21 Mar 86 06:07:20 EST
Received: from tektronix by csnet-relay.csnet id ag05170; 21 Mar 86 5:49 EST
Received: by tektronix (5.31/5.14)
id AA16652; Thu, 20 Mar 86 10:39:28 PST
Received: by tekchips (5.31/5.14)
id AA00496; Thu, 20 Mar 86 10:42:09 PST
Message-Id: <8603201842.AA00496@tekchips>
To: JINX%OZ.AI.MIT.EDU@xx.lcs.mit.edu
Cc: RRRS-AUTHORS%MIT-MC%tektronix.csnet@CSNET-RELAY.ARPA
Subject: Re: S&I's idea of EQ?
In-Reply-To: Your message of 19 Mar 1986 22:04 EST (Wed).
<JINX.12192088922.BABYL@MIT-OZ>
Date: 20 Mar 86 10:42:02 PST (Thu)
From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
As numbers demonstrate, it is both possible and useful to manipulate
objects without side effecting them. As I recall, S&ICP uses only
the make-environment and eval operations on environments, neither of
which mutates an environment. I can imagine many other
non-side-effecting operations on environments, such as:
What happens to (eval '(define x 4) <some-environment>)?
You're quite right; the interpreter in chapter 4 of S&ICP side effects
the environment if x is not already bound. I don't have to like it,
but that's what it does. The only way I see to avoid side effects to
environments and also remain consistent with S&ICP and with RRRS is
by arranging never to have any unbound variables. I don't have to
like that either, but that's what I does.
1) Do you mean that an implementation might choose always to return
#!true on 2 different "closings" of the same lambda expression?
No, eq? gets to say #!true only if the procedures have identical
behavior aside from the fact that they are associated with distinct
locations. The procedure domain (E* --> K --> C) is the set
of continuous maps from arguments to expression continuations to command
continuations; despite this imposing explanation, an element of the
procedure domain is nothing more than the behavior of a procedure in
the intuitively simple model. Thus eq? procedures are behaviorally
indistinguishable.
2) I'm confused by your proposal. I think naive users would be
confused also. If models become too complicated, the language becomes
intractable. If the mathematics of the intuitively simple model are
less elegant, that may imply that the mathematic representation is not
adequate. In case of conflict, I will usually choose the intuitively
simple model since a new representation better suited to it may appear
tomorrow. One of the main reasons why Scheme has become popular (I
think) is that it is easy to learn. This proposal would complicate it
unnecessarily.
Truly naive users shouldn't be using eq? on anything but symbols.
(Some would say that truly sophisticated users don't need to use
eq? on anything but symbols. I haven't yet reached that stage.)
The intuitively simple model doesn't attach locations to procedures,
and allows us to explain that eq? doesn't work on procedures because
equality of procedures is computationally undecidable. That model
has been rejected, however, so we have to explain that eq? kind of
works on procedures, but is not entirely reliable because equality
of procedures is computationally undecidable. Instead of comparing
the procedures to see if they are equal, eq? looks at the computational
history of the procedures and returns #!true if they were created at
the same instant in time.
At this point we should admit that eq? is an example of bad language
design, but that we are stuck with it for historical reasons. We've
probably had to apologize for eq? earlier in connection with numbers,
so this is no big deal.
Up to now I've probably been saying more or less what's said in 6.001.
Some users will then ask, "Isn't that [the time at which a procedure
is created] implementation-dependent?" and I then say "Yes, it's
just like eq? on numbers.". I don't know what people say in 6.001,
but I suspect it's a lot more complicated than what I say.
The answer can't be to give the user an interpreter, because she
would then ask--assuming she is no longer naive--"But isn't the
interpreter just a particular implementation?" and she would be
right.
Users should have a healthy disrespect for the programming languages
they are forced to use, so there's no point in pretending that Scheme
makes sense in all its dark corners. You should hear me trying to help
people understand Common Lisp.
Peace, Will
∂21-Mar-86 0849 @MC.LCS.MIT.EDU:LSI.RAY@SPEECH.MIT.EDU A chipmunk scheme compiler
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 21 Mar 86 08:48:59 PST
Received: from SPEECH.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 21 MAR 86 11:48:44 EST
Date: Fri 21 Mar 86 11:47:06-EST
From: Raymond A. Schnitzler <LSI.RAY%MIT-SPEECH@MIT-MC.ARPA>
Subject: A chipmunk scheme compiler
To: scheme@MC.LCS.MIT.EDU
Is there one? That is, is there any way to get my scheme code to run
faster on the chipmunks? I am using scheme because I inherited a lot
of code, and the chipmunks because that is all that I know I have
access to. Can anyone help?
Thanks
Ray Schnitzler
-------
∂21-Mar-86 1101 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU A chipmunk scheme compiler
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 21 Mar 86 10:57:43 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 21 MAR 86 13:57:37 EST
Date: 21 Mar 1986 12:38 EST (Fri)
Message-ID: <JINX.12192510149.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: "Raymond A. Schnitzler" <LSI.RAY%MIT-SPEECH@MC.LCS.MIT.EDU>
Cc: scheme@MC.LCS.MIT.EDU
Subject: A chipmunk scheme compiler
In-reply-to: Msg of 21 Mar 1986 11:47-EST from Raymond A. Schnitzler <LSI.RAY%MIT-SPEECH at MIT-MC.ARPA>
Which chipmunks are you using? If you are using the ones in bldg 34
they are running an old version of MIT-Scheme for which there is no
compiler. The new version has one but it is relatively idiosincratic.
If you'd like a copy of the new system, get in touch with CPH@OZ
(Chris Hanson) or me.
∂21-Mar-86 1326 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: S&I's idea of EQ?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 21 Mar 86 13:26:14 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 21 Mar 86 16:21:22 EST
Received: from indiana by csnet-relay.csnet id a010699; 21 Mar 86 15:55 EST
Date: Fri, 21 Mar 86 14:16:49 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: jinx@oz.ai.mit.edu
Subject: Re: S&I's idea of EQ?
Cc: rrrs-authors@mc.lcs.mit.edu
MIT Scheme uses a somewhat modified stop and copy garbage collector
which originally increased performance significantly. I have no
current figures. On average code (compiled or not) the overhead
caused by the garbage collector is at worst 10% (% of time spent
garbage collecting vs. total time). I feel that this is completely
acceptable. Some of us (GJS in particular) don't believe very much on
optimizing consing, but rather in (very) large memories and very fast
garbage collectors.
In Chez Scheme, for a program using no assignments, creating no closures
with free variables, and using no call/cc, garbage collection overhead
from the system is 0%. This is a fairly common situation.
In allocation-intensive code, forcing a collection every 256K bytes, the
percentage of time spent in the collector seems to be about 10-12%.
(And Chez Scheme doesn't have any slow variable references or other
comparable overhead to pump up the total time.) When I am fortunate
enough to run on a machine with more than 2 MB of physcial memory
available, collections can happen less frequently. I have seen the
collection overhead for allocation-intensive code be as low as 3% on a
VAX 11/785 with 10MB of physical memory.
I would guess that for "average" code, the "worst-case" is around 1-2%
with a reasonably large physical memory.
The reason for the low overhead is that system allocation is held to a
minimum, not because I have a highly-tuned collector. Less allocation
means fewer collections.
∂21-Mar-86 1530 @MC.LCS.MIT.EDU:FACCROSS%WSUVM1.BITNET@WISCVM.WISC.EDU
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 21 Mar 86 15:28:28 PST
Received: from WISCVM.WISC.EDU by MC.LCS.MIT.EDU 21 Mar 86 18:21:48 EST
Received: from (VM1MAIL)WSUVM1.BITNET by WISCVM.WISC.EDU on 03/21/86 at
17:19:46 CST
Received: by WSUVM1 (Mailer X1.23) id 3041; Fri, 21 Mar 86 14:52:27 PLT
Date: Fri, 21 Mar 1986 14:50 PLT
From: George Cross <FACCROSS%WSUVM1.BITNET@WISCVM.WISC.EDU>
To: <SCHEME@MIT-MC.ARPA>
Is there a list of available SCHEME implementations around that someone
could mail to me? Thanks.
---- George
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
George R. Cross cross@wsu.CSNET
Computer Science Department cross%wsu@csnet-relay.ARPA
Washington State University faccross@wsuvm1.BITNET
Pullman, WA 99164-1210 (509)-335-6319/6636
Acknowledge-To: George Cross <FACCROSS@WSUVM1>
∂25-Mar-86 0323 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU S&I's idea of EQ?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 03:22:21 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 22 MAR 86 13:14:46 EST
Date: 22 Mar 1986 13:14 EST (Sat)
Message-ID: <JINX.12192778744.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
Cc: rrrs-authors@MC.LCS.MIT.EDU
Subject: S&I's idea of EQ?
In-reply-to: Msg of 21 Mar 1986 14:16-EST from Kent Dybvig <dyb%indiana.csnet at CSNET-RELAY.ARPA>
In Chez Scheme, for a program using no assignments, creating no closures
with free variables, and using no call/cc, garbage collection overhead
from the system is 0%. This is a fairly common situation.
This is the case for us also with compiled code. Upward funargs and
downward funargs to unknown procedures (eq? is unknown for this
purpose) are about the only closures being consed. The rare exception
is when more than one operator is possible in a combination, in which
case I wimped out and decided to force all possibilities (all the
known procedures which might become the operator of that
combination) to be closures for simplicity. I consider this a bug
which will be fixed eventually in the new compiler, but we do not
seem to lose because of it too often.
We still run mostly interpreted code which conses considerably more
often. Besides some problems which the compiler has, our debugger
currently cannot handle compiled code (in part because compiled code
is so irregular and the compiler leaves no debugging information
around). Interpreted code runs acceptably fast and is considerably
easier to debug.
∂25-Mar-86 0327 JAR@MC.LCS.MIT.EDU small changes
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 03:26:36 PST
Date: Sun, 23 Mar 86 18:10:53 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: small changes
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].859894.860323.JAR>
As the current editor of the RRRS, I would like to make the following to
last year's report.
If you have serious objections let me know. Otherwise I'll go ahead.
-----
Compatible changes:
- Allow identifiers to begin with tilde (↑) and underscore (←). These
characters can't begin numbers, and are allowed elsewhere in
identifiers, so this seems innocuous and reasonable. Was there some
reason this wasn't permitted in the first place?
- Allow the characters - and + in the middle of identifiers. I assume
this was an oversight.
- Define GCD and LCM to work on Gaussian integers. (Complex numbers
are inessential anyhow, so you won't be obliged to implement this - but
I'll tell you how if you care.)
- Define new procedures NUMERATOR and DENOMINATOR on nonzero Gaussian
rationals which return canonical numerator and denominator (denominator
will always be a positive integer).
- I don't know of anyone who is a NAMED-LAMBDA partisan, so I intend to
flush it. (It's not essential, anyhow.) However, I know there are some
people out there who are partial to REC, so I'll take the conservative
position again and leave it in (even though I and other MIT folks don't
like it).
-----
Incompatible change:
I'd like to change the meaning of (DEFINE (form var ...) body ...) so
that it's defined in terms of LAMBDA instead of NAMED-LAMBDA. The only
reason this existed in the first place, I think, was because that's the
way MIT Scheme's DEFINE was defined. But on talking individually with
many people at MIT and elsewhere, I find that no one likes this
semantics and would rather have the simpler expansion in terms of
LAMBDA.
-----
I have made all of Will's suggested "non-controversial changes", and
have also changed the description of DO as previously discussed, which
appears to be non-controversial.
I am preparing a complete almost-context-free grammar for an appendix
which I'll electronically mail out for review. I'll try to US mail the
whole report to everyone in about a week, then wait for feedback, make
final changes, and ship it off to SIGPLAN.
Jonathan
∂25-Mar-86 0328 JAR@MC.LCS.MIT.EDU Scheme BNF
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 03:28:12 PST
Date: Sun, 23 Mar 86 20:38:01 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: Scheme BNF
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].859967.860323.JAR>
Here is a draft of my proposed BNF for the RRRS appendix. I would like
people to check it for correctness and completeness, and make other
appropriate remarks.
It will of course be properly fonted and explained in the report, with
discussion of *, +, whitespace, ambiguities (there are lots), etc. I'll
try to come up with some way to distinguish essential features from
non-essential ones.
I'm not enamored of the names of the nonterminals, and would be happy to
entertain alternatives.
A couple of minor problems in the explanations have been exposed by this
exercise, which I'll quietly fix. For example, (DEFINE (FOO . X) ...)
isn't defined to work in the current report, although I'm sure it does
work in everyone's implementation.
Questions:
- Does anyone object to defining (COND) and (CASE) to return unspecified
values? I think this would be a good idea.
- Shouldn't backquote work on vectors? If not, then what's the rationale
for making them work on lists and not vectors?
- What kinds of constants should be allowed in CASE clauses? I don't
really care, but I can imagine two possible answers:
1. If EQV? is used for comparisons, then it doesn't make any sense to allow
strings, lists, or vectors. So these should be disallowed by the syntax.
This makes the grammar a little more complicated, since one has to define
what it means for something to be a "casable constant" (I'll come up with a
better name than that).
<case clause> ::= ((<casable>*) <sequence>)
<casable> ::= <boolean> | <number> | <character> | <symbol>
2. Use EQUAL? for comparisons, and allow any <datum>. This makes the
grammar simpler and makes previously undefined and possibly useful
syntaxes meaningful. This is an extension to the language, which some
people might object to as being too liberal and/or not useful enough to
warrant a change. (There's definitely no efficiency loss except in a
very stupid interpreter.) If no one objects, I'll do this, but I won't
argue if anyone does object, but I won't listen to anyone who doesn't
supply a better word to use for the nonterminal than "casable".
<case clause> ::= ((<datum>*) <sequence>)
- I definitely want like to flush the (<var>) syntax for iteration specs in
DO. It is inconsistent for DO to have this alternate form and not LET,
and I don't like either. Does anyone actually ever use it?
- I would also like to flush the (<var> <init>) syntax for DO iteration
specs. Does anyone ever use this? I always wrap the DO in a LET if I
need extra bindings. No replies from people who don't use DO, please.
- Oh yeah, I forgot to mention in my previous message that I would like to
document DELAY and FORCE, as non-essential special form and procedure,
respectively. I believe they're non-controversial, and desirable given
that they have a central role in S&ICP and are a little tricky to
describe and implement.
----------
<file> ::= <form>* ;This is what LOAD presumably parses
<form> ::= <expression> | <definition>
;This is what a read-eval-print might parse
<expression> ::= <constant> | <variable>
| <procedure call>
| <quotation>
| (lambda <bound var list> <body>)
| (if <test> <consequent> <alternate>)
| (if <test> <consequent>)
| (cond <cond clause>*)
| (cond <cond clause>* (else <sequence>))
| (and <expression>*)
| (or <expression>*)
| (case <case clause>*)
| (case <case clause>* (else <sequence>))
| (let (<binding spec>*) <body>)
| (let <variable> (<binding spec>*) <body>)
| (let* (<binding spec>*) <body>)
| (letrec (<binding spec>*) <body>)
| (rec <variable> <expression>)
| (set! <variable> <expression>)
| (begin <sequence>)
| (sequence <sequence>)
| (do (<iteration spec>*) (<end test> <sequence>+) <expression>*)
| (delay <expression>)
| <quasiquotation>
<variable> ::= <identifier>
<procedure call> ::= (<operator> <operand>*)
<operator> ::= <expression>
<operands> ::= <expression>*
<quotation> ::= '<datum> | (quote <datum>)
<body> ::= <definition>* <sequence>
<sequence> ::= <expression>+
<definition> ::= (define <variable> <expression>)
| (define <call pattern> <body>)
<call pattern> ::= (<pattern> <variable>*)
| (<pattern> <variable>* . <variable>)
<pattern> ::= <variable> | <call pattern>
<bound var list> ::= <variable>
| (<variable>*) | (<variable>+ . <variable>)
<test> ::= <expression>
<consequent> ::= <expression>
<alternate> ::= <expression>
<cond clause> ::= (<test> <sequence>) | (<test> => <expression>)
<case clause> ::= ((<datum>*) <sequence>)
<binding spec> ::= (<variable> <expression>)
<iteration spec> ::= (<variable> <init> <step>)
<quasiquotation> ::= <quasiquotation 0>
<template 0> ::= <expression>
Repeat the following for N = 1 to infinity:
<quasiquotation N> ::= `<template N+1> | (quasiquote <template N+1>)
<template N> ::= <constant> | <symbol>
| <list template N>
| <vector template N>
| <unquotation N>
<seq template N> ::= <template N> | <splicing unquotation N>
<list template N> ::= (<seq template N>*)
| (<seq template N>+ . <template N>)
| <quasiquotation N+1>
<vector template N> ::= #(<seq template N>*)
<unquotation N> ::= ,<template N-1> | (unquote <template N-1>)
<splicing unquotation N> ::= ,@<template N-1>
| (unquote-splicing <template N-1>)
end repeat
The grammar for external representations of objects from here on down is
self-contained. <datum> is what READ parses. Note that any string
which is an <expression> must also be a <datum>.
<datum> ::= <constant> | <symbol> | <list> | <vector>
<constant> ::= <boolean> | <number> | <character> | <string>
<symbol> ::= <identifier>
<boolean> ::= #!true | #!false
<string> ::= " <string element>* "
<string element> ::= <any character other than " or \> | \" | \\
<list> ::= ( <datum>* ) | ( <datum>+ . <datum> )
| <abbreviation>
<abbreviation> ::= <abbrev prefix> <datum>
<abbrev prefix> ::= ' | ` | , | ,@
<vector> ::= #( <datum>* )
<identifier> ::= <initial> <subsequent>* | <peculiar identifier>
<initial> ::= <letter> | <special initial>
<letter> ::= A | B | C | ... | Z
<special initial> ::= ! | $ | % | & | * | / | : | < | = | > | ? | ~ | ← | ↑
<subsequent> ::= <initial> | <digit> | <special subsequent>
<digit> ::= 0 | 1 | ... | 9
<special subsequent> ::= . | + | -
<peculiar identifier> ::= + | - | 1+ | -1+
<number> ::= ... the grammar for numbers ...
∂25-Mar-86 0335 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@mc.lcs.mit.edu S&I's idea of EQ?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 03:25:44 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 23 Mar 86 17:50:28 EST
Received: from tektronix by csnet-relay.csnet id a025609; 23 Mar 86 5:26 EST
Received: from csnet-relay by tektronix.tektronix.CSNET id ar28308;
23 Mar 86 2:24 PST
Received: from mc.lcs.mit.edu by CSNET-RELAY.ARPA id a022623;
22 Mar 86 21:45 EST
Date: 22 Mar 1986 21:44 EST (Sat)
Message-ID: <JINX.12192871582.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@xx.lcs.mit.edu>
To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
Cc: JINX%OZ.AI.MIT.EDU@xx.lcs.mit.edu,
RRRS-AUTHORS%MIT-MC%tektronix.csnet@CSNET-RELAY.ARPA
Subject: S&I's idea of EQ?
In-reply-to: Msg of 20 Mar 1986 13:42-EST from willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
Truly naive users shouldn't be using eq? on anything but symbols.
(Some would say that truly sophisticated users don't need to use
eq? on anything but symbols. I haven't yet reached that stage.)
What about pairs and other mutable objects? Procedures with state are
effectively mutable (some more opaquely than others of course) and
this is the main reason for desiring EQ? to work on them.
At this point we should admit that eq? is an example of bad language
design, but that we are stuck with it for historical reasons. We've
probably had to apologize for eq? earlier in connection with numbers,
so this is no big deal.
This is the reason JAR and I agreed that it was acceptable to both if
EQ? was optional as long as if present it had the "traditional"
properties (implying no coalescing or splitting). Unfortunately other
people thought that this was not a viable answer.
There is a difference with numbers. There is a well defined predicate
(= or =?) which is appropriate, so eq? is superfluous and its
behaviour can well be implementation dependent. On the other hand,
procedures can have internal state and there is no other predicate
defined on them.
The intuitively simple model doesn't attach locations to procedures,
I disagree. The moment that internal state appears, it becomes
apparent that there are locations associated with procedures.
and allows us to explain that eq? doesn't work on procedures because
equality of procedures is computationally undecidable.
This is only slightly worse than the problem with equal? and
circularity. It seems to me that you are trying to give eq? a sort of
"equal?ish" semantics for procedures, but this would be inconsistent
with its behaviour on other types.
That model
has been rejected, however, so we have to explain that eq? kind of
works on procedures, but is not entirely reliable because equality
of procedures is computationally undecidable. Instead of comparing
the procedures to see if they are equal, eq? looks at the computational
history of the procedures and returns #!true if they were created at
the same instant in time.
If coalescing is allowed (by default) this instant of time becomes
something controlled by the compiler and not the programmer. My
understanding of programs (and I believe of many other people around
here) comes from having a detailed and accurate model of their
execution. This optimization violates this understanding in a
fundamental way, and would make it very confusing to me. Particularly
so since I would have no way in general of bypassing this optimization
and forcing the order that I would like.
It seems to me that the question of whether coalescing is allowed is
only a matter of efficiency. I'm perfectly happy to have it as an
explicit optimization to be allowed by the user, but it seems
excesive to allow it by default. Again, why do people object to a
declaration to this purpose?
∂25-Mar-86 0342 @MC.LCS.MIT.EDU:F.AE@DEEP-THOUGHT.MIT.EDU Scheme implementation guide
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 03:28:04 PST
Received: from DEEP-THOUGHT.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 23 MAR 86 18:27:44 EST
Date: Sun 23 Mar 86 18:27:39-EST
From: Antonio Elias <F.AE@DEEP-THOUGHT.MIT.EDU>
Subject: Scheme implementation guide
To: scheme@MC.LCS.MIT.EDU
Message-ID: <12193097983.16.F.AE@DEEP-THOUGHT.MIT.EDU>
I, too, would be interested in a "guide to scheme implementations",
maintained in a friendly (and ftp-able) system, listing all the known
real or quasi-real implementations with perhaps some words of wisdom
on each of them, availability, etc. etc.
- Antonio
-------
∂25-Mar-86 0351 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU small changes
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 03:49:21 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 24 MAR 86 12:51:33 EST
Date: 24 Mar 1986 12:46 EST (Mon)
Message-ID: <JINX.12193298036.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: small changes
In-reply-to: Msg of 23 Mar 1986 18:10-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
I am a partisan of NAMED-LAMBDA. If REC stays, I believe so should
NAMED-LAMBDA. I'm prefectly happy to flush both.
∂25-Mar-86 0352 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU small changes
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 03:49:38 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 24 MAR 86 12:55:03 EST
Date: 24 Mar 1986 12:54 EST (Mon)
Message-ID: <JINX.12193299492.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: small changes
In-reply-to: Msg of 23 Mar 1986 18:10-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
I'd like to change the meaning of (DEFINE (form var ...) body ...) so
that it's defined in terms of LAMBDA instead of NAMED-LAMBDA. The only
reason this existed in the first place, I think, was because that's the
way MIT Scheme's DEFINE was defined. But on talking individually with
many people at MIT and elsewhere, I find that no one likes this
semantics and would rather have the simpler expansion in terms of
LAMBDA.
While I agree that it should have been like this, I thought that the
only reason to add the more complicated defines was for compatibility
with MIT-Scheme. MIT-Scheme has not changed, and there would be a big
argument over it (at least as far as the student system is concerned).
It seems useless to add it then if it is going to be incompatible
anyway.
∂25-Mar-86 0351 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA Scheme BNF
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 03:49:06 PST
Received: from GODOT.THINK.COM by MC.LCS.MIT.EDU 24 Mar 86 12:51:07 EST
Received: from wenceslas by GODOT.THINK.COM via CHAOS; Mon, 24 Mar 86 12:50:50 est
Date: Mon, 24 Mar 86 12:52 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: Scheme BNF
To: JAR@MC.LCS.MIT.EDU, RRRS-AUTHORS@MC.LCS.MIT.EDU
Cc: gls@THINK-AQUINAS.ARPA
In-Reply-To: <[MC.LCS.MIT.EDU].859967.860323.JAR>
Message-Id: <860324125242.3.GLS@THINK-WENCESLAS.ARPA>
Date: Sun, 23 Mar 86 20:38:01 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
[JAR's original message appears below only in excerpts. I am working
with the AI Memo 848 version of RRRS, if that matters.]
- Does anyone object to defining (COND) and (CASE) to return unspecified
values? I think this would be a good idea.
I think these cases already follow from the discussion on page 14, which says
that if no guard or selector is satisfied then the result is unspecified.
I don't object to drawing attention to these cases explicitly.
- Shouldn't backquote work on vectors? If not, then what's the rationale
for making them work on lists and not vectors?
Yes. I observe that backquote works on vectors in Common Lisp (but not on
structures, more's the pity).
- What kinds of constants should be allowed in CASE clauses? I don't
really care, but I can imagine two possible answers:
1. If EQV? is used for comparisons, then it doesn't make any sense to allow
strings, lists, or vectors.
In the context of Common Lisp, it does make sense because one could use
backquote (for example) to construct a CASE expression with a cons cell
as a selector and then feed this expression to EVAL. It probably makes
less sense in a SCHEME that does not have the ENCLOSE operation.
- I definitely want like to flush the (<var>) syntax for iteration specs in
DO. It is inconsistent for DO to have this alternate form and not LET,
and I don't like either. Does anyone actually ever use it?
I have no strong opinion on this.
- I would also like to flush the (<var> <init>) syntax for DO iteration
specs. Does anyone ever use this? I always wrap the DO in a LET if I
need extra bindings. No replies from people who don't use DO, please.
I'm a user of DO, and I draw the following distinction when I write code: a
variable bound by a LET wrapped around the DO is merely naming a quantity used a
lot within the DO, but that value will not change, whereas a variable bound in
the DO itself is explicitly updated by the DO loop using SET! (usually in the
body) in a way that is too complicated to be conveniently expressed as a step-form.
Regarding the grammar: (a) The handling of quasiquotation is very nice. (b)
There is a confusion in the grammar: some parts of it deal in strings of tokens,
and other parts in strings of characters. On the face of it it is unclear why
spaces can be interpolated to produce "(a b c)" instead of "(abc)" in the grammar
for a list but spaces may not be interpolated to produce "f o o b a z" instead of
"foobaz" in the grammar for a symbol. The grammar should be divided in the usual
way into a character-based lexical grammar for tokens and a token-based parsing
grammar for expressions.
--Guy
∂25-Mar-86 0351 @MC.LCS.MIT.EDU:MHWU%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Partisans of NAMED-LAMBDA
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 03:49:30 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 24 MAR 86 12:54:22 EST
Date: Mon 24 Mar 86 12:54:00-EST
From: "Henry M. Wu" <MHWU%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
Subject: Partisans of NAMED-LAMBDA
To: rrrs-authors@MC.LCS.MIT.EDU
Message-ID: <12193299388.74.MHWU@OZ.AI.MIT.EDU>
I like NAMED-LAMBDA and wish it won't go away.
I guess that makes me Jon Rees's first NAMED-LAMBDA partisan. I suspect
a lot more will follow.
Henry Wu
-------
∂25-Mar-86 0351 @MC.LCS.MIT.EDU:ramsdell%linus@mitre-bedford.ARPA Expunge LETREC, BEGIN and SEQUENCE.
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 03:48:49 PST
Received: from mitre-bedford.ARPA by MC.LCS.MIT.EDU 24 Mar 86 11:48:21 EST
Organization: The MITRE Corp., Bedford, MA
Received: by linus.MENET (4.12/4.7)
id AA14182; Mon, 24 Mar 86 07:00:16 est
Date: Mon, 24 Mar 86 07:00:16 est
From: John D. Ramsdell <ramsdell%linus@mitre-bedford.ARPA>
Posted-Date: Mon, 24 Mar 86 07:00:16 est
Message-Id: <8603241200.AA14182@linus.MENET>
To: rrrs-authors@mit-mc.ARPA
Subject: Expunge LETREC, BEGIN and SEQUENCE.
I have a proposal that eliminates the need to
modify lambda environments by local defines,
and at the same time eliminates the need for
LETREC, BEGIN and SEQUENCE.
For expository purposes, I will introduce the
special form DECLARE defined as:
(DECLARE
(DEFINE a z)
(DEFINE b y)
...
(DEFINE e r)
statement1
statement2
...
statementn)
==>
(LETREC
((a z)
(b y)
...
(e r))
statement1
statement2
...
statementn)
In clsch, the macro is:
(define-macro (declare . forms)
(let loop ((forms forms)
(decls '()))
(let ((def (car forms)))
(if (and (pair? def) (eq? 'define (car def)))
(loop (cdr forms) (cons (cdr def) decls))
`(letrec ,decls . ,forms)))))
Clearly, DECLARE is a simple generalization of BEGIN.
It allows LETREC-like declarations in DEFINE syntax.
This interpretation of local defines suggests that they
do not modify environments, but create their own. I'm
sure that will help those interested in good code.
My proposal is to treat every sequence of statements as
a DECLARE form. This includes the bodies of LAMBDAs,
LETs, DOs and COND clauses minus the guard. Then we can
expunge LETREC, BEGIN and SEQUENCE.
John
∂25-Mar-86 0353 @MC.LCS.MIT.EDU:OXLEY%ti-csl.csnet@CSNET-RELAY.ARPA Re: Scheme BNF
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 03:49:46 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 24 Mar 86 12:57:02 EST
Received: from ti-csl by csnet-relay.csnet id ad08189; 24 Mar 86 12:34 EST
Received: by tilde id AA26690; Mon, 24 Mar 86 08:50:18 cst
Date: Mon 24 Mar 86 08:39:00-CST
From: Don Oxley <OXLEY@ti-csl.CSNET>
Subject: Re: Scheme BNF
To: JAR%mc.lcs.mit.edu@CSNET-RELAY.ARPA,
RRRS-AUTHORS%mc.lcs.mit.edu@CSNET-RELAY.ARPA
In-Reply-To: <[MC.LCS.MIT.EDU].859967.860323.JAR>
Message-Id: <12193263890.36.OXLEY@CSC60>
Sorry to ask for a delay, but David Bartley is on vacation for a couple
of weeks. I would really like to get his input before we at TI take any
positions (I don't think we will have any serious problems - I'd just
like for us to get our act together before we respond).
--Don
-------
∂25-Mar-86 0353 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: Scheme BNF
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 03:51:22 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 24 Mar 86 13:47:36 EST
Received: from indiana by csnet-relay.csnet id aa08451; 24 Mar 86 13:03 EST
Date: Mon, 24 Mar 86 10:39:14 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: rrrs-authors@mc.lcs.mit.edu
Subject: Re: Scheme BNF
Questions:
Answers and more questions:
- Does anyone object to defining (COND) and (CASE) to return unspecified
values? I think this would be a good idea.
I thought that COND and CASE with no match and no ELSE were already defined
to return unspecified values. If not, I think this should be the definition.
Can we also have (BEGIN) return an unspecified value instead of being invalid
syntax?
- Shouldn't backquote work on vectors? If not, then what's the rationale
for making them work on lists and not vectors?
I think it should not work on vectors. It makes sense to me only in non-
constants, and until we make a firm statement that vectors have some useful
meaning in Scheme other than as constants, backquote should not work within
vectors. I also have some amount of hesitance about splicing a list into
a vector, etc., and what that would mean.
- What kinds of constants should be allowed in CASE clauses? I don't
really care, but I can imagine two possible answers:
1. If EQV? is used ...
<case clause> ::= ((<casable>*) <sequence>)
<casable> ::= <boolean> | <number> | <character> | <symbol>
2. Use EQUAL? for comparisons, ...
<case clause> ::= ((<datum>*) <sequence>)
I do not like the use of EQUAL?. If you don't like <casable>, how about
<atom>? Seriously, we need some term anyway, since it is the same thing
accepted by EQV?. What about <simple>? Or <tag>?)
Also, it's been said before, but I think we should allow for the optional
syntax of a single "<casable>" not in a list.
<case clause> ::= (<datum> <sequence>)
- I definitely want like to flush the (<var>) syntax for iteration specs in
DO. It is inconsistent for DO to have this alternate form and not LET,
and I don't like either. Does anyone actually ever use it?
- I would also like to flush the (<var> <init>) syntax for DO iteration
specs. Does anyone ever use this? I always wrap the DO in a LET if I
need extra bindings. No replies from people who don't use DO, please.
I agree completely with your sentiments, and I do use DO.
- Oh yeah, I forgot to mention in my previous message that I would like to
document DELAY and FORCE, as non-essential special form and procedure,
respectively. I believe they're non-controversial, and desirable given
that they have a central role in S&ICP and are a little tricky to
describe and implement.
If you don't mind, please send out your prose for these and include the
appropriate code for them. I don't have them in Chez Scheme yet and I'm
not in the mood to think.
Picky comment:
I am uncomfortable with the use of <sequence> in light of the existence
of sequence as a special form. Furthermore, I think that <expression>+
would be more expressive where it appears, and in Scheme there should be
no confusion with the operator + or sign +.
∂25-Mar-86 0352 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU small changes
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 03:51:33 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 24 MAR 86 14:24:11 EST
Date: 24 Mar 1986 13:59 EST (Mon)
Message-ID: <JINX.12193311389.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
Cc: rrrs-authors@MC.LCS.MIT.EDU
Subject: small changes
In-reply-to: Msg of 24 Mar 1986 10:13-EST from Kent Dybvig <dyb%indiana.csnet at CSNET-RELAY.ARPA>
Can we flush internal DEFINE and get Abelson & Sussman w/Sussman to make
a new edition without it?
I would object as strongly as I possibly could to this (and other
people at MIT would also). It is not essential as it is, and does not
imply first class environments or side-effected lambda environments
anyway. The only thing it implies (if anything), is a more
complicated LAMBDA special form to "scan out" the defines and "turn
them into" LETREC.
I would also like to bring up the case insensitivity issue once again.
Yes, I do prefer that A-Symbol and a-symbol be different. I like to use
case to set off certain things, like X for set and x for the element in
(member x X). I see no value in having case-insensitive symbols, and
a lot of conversion trouble. I think most of us now have terminals with
lower-case letters. I would like the special-form keywords and function
names to be in lower case.
I find C impossibly hard to read precisely because people use
identifiers which differ only in case for different things. This is
even worse than the dual environment of Common Lisp (value cell vs.
function cell).
Natural languages do not usually have different meanings for words
with different capitalizations.
(if (If iF) (IF iF) (If If)) ;yipee!
∂25-Mar-86 0352 ALAN@MC.LCS.MIT.EDU small changes
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 03:47:27 PST
Date: Sun, 23 Mar 86 21:05:39 EST
From: Alan Bawden <ALAN@MC.LCS.MIT.EDU>
Subject: small changes
To: JAR@MC.LCS.MIT.EDU
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Sun 23 Mar 86 18:10:53 EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
Message-ID: <[MC.LCS.MIT.EDU].859993.860323.ALAN>
Date: Sun, 23 Mar 86 18:10:53 EST
From: Jonathan A Rees <JAR at MC>
- Define GCD and LCM to work on Gaussian integers. (Complex numbers
are inessential anyhow, so you won't be obliged to implement this - but
I'll tell you how if you care.)
- Define new procedures NUMERATOR and DENOMINATOR on nonzero Gaussian
rationals which return canonical numerator and denominator (denominator
will always be a positive integer).
Super. I wanted these two in Common Lisp, but they were overlooked in the
rush apparently. But you have to be careful about how you state the
contract. What you have here is incorrect.
GCD on integers always returns a non-negative result. On Gausian rationals
you have to define some region of the complex plane that should contain the
answer. You want it to include the non-negative integers for compatibility
with the non-Gausian case. I would recommend
{ a+bi | a>0 & b>=0 or a=0 & b=0 }, which consists of the "first quadrant"
and the non-negative real axis.
LCM is constrained similarly for similar reasons.
DENOMINATOR should also be defined to return a Gausian integer in the same
region. It would be -incorrect- to always return a positive integer! For
example, given (3/2)-(3/2)i, DENOMINATOR should return 1+i, since in lowest
terms (3/2)-(3/2)i is 3/(1+i).
∂25-Mar-86 0353 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Expunge LETREC, BEGIN and SEQUENCE.
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 03:50:06 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 24 MAR 86 13:28:07 EST
Date: 24 Mar 1986 13:03 EST (Mon)
Message-ID: <JINX.12193301162.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: "John D. Ramsdell" <ramsdell%linus@MITRE-BEDFORD.ARPA>
Cc: rrrs-authors@MC.LCS.MIT.EDU
Subject: Expunge LETREC, BEGIN and SEQUENCE.
In-reply-to: Msg of 24 Mar 1986 07:00-EST from John D. Ramsdell <ramsdell%linus at mitre-bedford.ARPA>
Local defines in MIT-Scheme (which I believe is the only one that
originally implemented them) do not cause side effects to
environments.
(define (foo x)
(define (bar y)
(+ y (baz x)))
(define (baz w)
(* w x))
...
)
is equivalent to
(define (foo x)
(letrec ((bar (named-lambda (bar y) (+ y (baz x))))
(baz (named-lambda (baz w) (* w x))))
...))
∂25-Mar-86 0353 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: small changes
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 03:49:55 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 24 Mar 86 13:20:48 EST
Received: from indiana by csnet-relay.csnet id a008451; 24 Mar 86 13:02 EST
Date: Mon, 24 Mar 86 10:13:39 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: rrrs-authors@mc.lcs.mit.edu
Subject: Re: small changes
As the current editor of the RRRS, I would like to make the following to
last year's report.
If you have serious objections let me know. Otherwise I'll go ahead.
-----
Compatible changes:
- Allow identifiers to begin with tilde (↑) and underscore (←). These
characters can't begin numbers, and are allowed elsewhere in
identifiers, so this seems innocuous and reasonable. Was there some
reason this wasn't permitted in the first place?
- Allow the characters - and + in the middle of identifiers. I assume
this was an oversight.
I would like to see the Common Lispy definition that anything with no
other possible syntax (especially wrt numbers) is an identifier. I don't
necessarily like it, but I see no reason to do otherwise, and I might
be interested sometime in implementing Common Lisp in Scheme.
- I don't know of anyone who is a NAMED-LAMBDA partisan, so I intend to
flush it. (It's not essential, anyhow.) However, I know there are some
people out there who are partial to REC, so I'll take the conservative
position again and leave it in (even though I and other MIT folks don't
like it).
Thank you for leaving in REC. I could not live without it.
Incompatible change:
I'd like to change the meaning of (DEFINE (form var ...) body ...) so
that it's defined in terms of LAMBDA instead of NAMED-LAMBDA. The only
reason this existed in the first place, I think, was because that's the
way MIT Scheme's DEFINE was defined. But on talking individually with
many people at MIT and elsewhere, I find that no one likes this
semantics and would rather have the simpler expansion in terms of
LAMBDA.
Can we flush internal DEFINE and get Abelson & Sussman w/Sussman to make
a new edition without it?
I have made all of Will's suggested "non-controversial changes", and
have also changed the description of DO as previously discussed, which
appears to be non-controversial.
I've forgotten what the non-controversioal changes to DO are. Perhaps
you could refresh my memory. I hope it was related to the implied use of
set! in the description used in the manual. I would to be able to define
DO as:
(do ((x v u ...) ...) (t r ...) e ...)
==>
((rec loop
(lambda (x ...)
(if t
(begin r ...)
(begin e ... (loop u ...)))))
v ...)
I would also like to bring up the case insensitivity issue once again.
Yes, I do prefer that A-Symbol and a-symbol be different. I like to use
case to set off certain things, like X for set and x for the element in
(member x X). I see no value in having case-insensitive symbols, and
a lot of conversion trouble. I think most of us now have terminals with
lower-case letters. I would like the special-form keywords and function
names to be in lower case.
On one other issue, there are some of us here at IU who have serious
difficulty with #!true and #!false, and we will be sending out a new
proposal under separate cover in a day or so.
Kent
∂25-Mar-86 0408 JAR@MC.LCS.MIT.EDU small changes
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 04:07:37 PST
Date: Mon, 24 Mar 86 17:59:41 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: small changes
To: JINX@OZ.AI.MIT.EDU
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of 24 Mar 1986 12:54 EST (Mon) from Bill Rozas <JINX%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
Message-ID: <[MC.LCS.MIT.EDU].860716.860324.JAR>
Date: 24 Mar 1986 12:54 EST (Mon)
From: Bill Rozas <JINX%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
While I agree that it should have been like this, I thought that the
only reason to add the more complicated defines was for compatibility
with MIT-Scheme. MIT-Scheme has not changed, and there would be a big
argument over it (at least as far as the student system is concerned).
It seems useless to add it then if it is going to be incompatible
anyway.
No, I see other reasons to have (define (...) ...). The first is that
it's used in S&ICP - notably, with the semantics I want (see page 303).
The second is that some people like to use it; in particular, myself,
and most T users, I think. And if it exists, I think the documentation
would be clearer and simpler if it were the other way.
∂25-Mar-86 0509 JAR@MC.LCS.MIT.EDU small changes
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 05:09:18 PST
Date: Mon, 24 Mar 86 17:59:41 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: small changes
To: JINX@OZ.AI.MIT.EDU
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of 24 Mar 1986 12:54 EST (Mon) from Bill Rozas <JINX%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
Message-ID: <[MC.LCS.MIT.EDU].860716.860324.JAR>
Date: 24 Mar 1986 12:54 EST (Mon)
From: Bill Rozas <JINX%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
While I agree that it should have been like this, I thought that the
only reason to add the more complicated defines was for compatibility
with MIT-Scheme. MIT-Scheme has not changed, and there would be a big
argument over it (at least as far as the student system is concerned).
It seems useless to add it then if it is going to be incompatible
anyway.
No, I see other reasons to have (define (...) ...). The first is that
it's used in S&ICP - notably, with the semantics I want (see page 303).
The second is that some people like to use it; in particular, myself,
and most T users, I think. And if it exists, I think the documentation
would be clearer and simpler if it were the other way.
∂25-Mar-86 0525 JAR@MC.LCS.MIT.EDU Scheme implementation guide
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 05:25:18 PST
Date: Sun, 23 Mar 86 20:43:45 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: Scheme implementation guide
To: F.AE@DEEP-THOUGHT.MIT.EDU
cc: SCHEME@MC.LCS.MIT.EDU
In-reply-to: Msg of Sun 23 Mar 86 18:27:39-EST from Antonio Elias <F.AE at DEEP-THOUGHT.MIT.EDU>
Message-ID: <[MC.LCS.MIT.EDU].859975.860323.JAR>
You can FTP this from "SCHEME; SCHEME IMPLS" on MC. One of these days
I'll compress it down to fewer than 10K bytes so that it's easy for me
to mail - MC's mailer doesn't like messages bigger than that, and it's
currently almost 17K.
I still don't have information about T or MIT Scheme in that file; sure
would be nice if someone from those groups would send out a message
about status, availability, etc., hint hint. E.g. word comes to me that
T has or will soon have the same "free software" copyright notice that
MIT Scheme does.
∂25-Mar-86 0541 JAR@MC.LCS.MIT.EDU Scheme BNF
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 05:41:02 PST
Date: Mon, 24 Mar 86 18:03:28 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: Scheme BNF
To: dyb%indiana.csnet@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Mon 24 Mar 86 10:39:14 est from Kent Dybvig <dyb%indiana.csnet at CSNET-RELAY.ARPA>
Message-ID: <[MC.LCS.MIT.EDU].860721.860324.JAR>
Date: Mon, 24 Mar 86 10:39:14 est
From: Kent Dybvig <dyb%indiana.csnet at CSNET-RELAY.ARPA>
- Does anyone object to defining (COND) and (CASE) to return unspecified
values? I think this would be a good idea.
I thought that COND and CASE with no match and no ELSE were already defined
to return unspecified values. If not, I think this should be the definition.
No, it's not defined at all - it could be a syntax error, for example.
Can we also have (BEGIN) return an unspecified value instead of being invalid
syntax?
I am certainly opposed to this.
∂25-Mar-86 0723 @MC.LCS.MIT.EDU:ramsdell%linus@mitre-bedford.ARPA Expunge NAMED-LAMBDA
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 07:23:15 PST
Received: from mitre-bedford.ARPA by MC.LCS.MIT.EDU 25 Mar 86 09:43:40 EST
Organization: The MITRE Corp., Bedford, MA
Received: by linus.MENET (4.12/4.7)
id AA19757; Tue, 25 Mar 86 07:43:11 est
Date: Tue, 25 Mar 86 07:43:11 est
From: John D. Ramsdell <ramsdell%linus@mitre-bedford.ARPA>
Posted-Date: Tue, 25 Mar 86 07:43:11 est
Message-Id: <8603251243.AA19757@linus.MENET>
To: rrrs-authors@mit-mc.ARPA
Subject: Expunge NAMED-LAMBDA
I would like to see NAMED-LAMBDA go.
John
∂25-Mar-86 1258 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: small changes
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 12:57:45 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 25 Mar 86 15:03:27 EST
Received: from indiana by csnet-relay.csnet id aa21173; 25 Mar 86 14:38 EST
Date: Mon, 24 Mar 86 16:28:58 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: jinx@mc.lcs.mit.edu
Subject: Re: small changes
Cc: rrrs-authors@mc.lcs.mit.edu
Can we flush internal DEFINE and get Abelson & Sussman w/Sussman to make
a new edition without it?
I would object as strongly as I possibly could to this (and other
people at MIT would also). It is not essential as it is, and does not
imply first class environments or side-effected lambda environments
anyway. The only thing it implies (if anything), is a more
complicated LAMBDA special form to "scan out" the defines and "turn
them into" LETREC.
This was intended in jest, but since you responded, I have to give my
reasoning. Inclusion of internal define is indeed optional, but it
does destroy one of our (people at Indiana) favorite programming styles,
namely the use of define within let to establish one or more globally
visible values sharing internal identifiers, especially state variables
and help functions:
(let ([state-var1 ...] ...
[help-fcn1 (lambda (...) ...)] ...)
(define var1 ...)
(define var2 ...))
We do not view the use "empty" defines outside and set! inside as a
viable alternative, since that is clumsy and implies assignment rather
than definition.
As for defense of the feature itself, I feel that gumming up LAMBDA is
the worst possible thing we can do to Scheme. It wasn't so long ago
that it was a page of code to write a full Scheme interpreter. Now it
is a page of code to handle lambda alone!
I would also like to bring up the case insensitivity issue once again.
Yes, I do prefer that A-Symbol and a-symbol be different. I like to use
case to set off certain things, like X for set and x for the element in
(member x X). I see no value in having case-insensitive symbols, and
a lot of conversion trouble. I think most of us now have terminals with
lower-case letters. I would like the special-form keywords and function
names to be in lower case.
I find C impossibly hard to read precisely because people use
identifiers which differ only in case for different things. This is
even worse than the dual environment of Common Lisp (value cell vs.
function cell).
I have the same problem with people who, in Lisp, use upper case in
some places and lower case in others and mean the same identifier.
Natural languages do not usually have different meanings for words
with different capitalizations.
(if (If iF) (IF iF) (If If)) ;yipee!
I disagree that natural languages do not usually have different
meanings for words with different captitalizations; some good
examples are given in a recent submission to SIGPLAN notices (Mark
Wells, V21 #3, March 86, p. 21). (The article in question is
actually rather interesting, if you filter out the advertisements
for Modcap.)
This is at best a sylistic issue that should not be enforced by an
otherwise useless and sometimes confusing restriction on the lexical
syntax of the language.
∂25-Mar-86 1303 JAR@MC.LCS.MIT.EDU (do ((var init)) (...))
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Mar 86 13:03:17 PST
Date: Tue, 25 Mar 86 16:05:09 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: (do ((var init)) (...))
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].861493.860325.JAR>
I've heard no one insisting on the (do ((var)) ...) syntax, so I'm going
to flush it, for consistency with LET. A few people say they like (do
((var init)) ...), so I'll leave it in. But there's one little issue
which needs to be clarified: does the var get a new binding every time
around the loop, or does it get just one binding at the beginning? That
is, is there an outer LET for the variables which aren't stepped, or is
(var init) the same as (var init var)? It makes a difference if
closures are created in the loop.
The easiest way to write the macro expander is to make (var init) be the
same as (var init var). I think this is what ancient scheme
interpreters like NSCHSY did, and it's certainly what T does. I don't
know about any other implementation. This is the interpretation that I
prefer - it's easier to describe and more useful and elegant. Speak up
if you believe this is wrong.
Jonathan
∂26-Mar-86 0609 @MC.LCS.MIT.EDU:abc%computer-science.nottingham.ac.uk@Cs.Ucl.AC.UK Scheme wanted
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 26 Mar 86 06:07:45 PST
Received: from Cs by MC.LCS.MIT.EDU 26 Mar 86 08:52:41 EST
Received: from computer-science.nottingham.ac.uk by 44d.Cs.Ucl.AC.UK
via Janet with NIFTP id a004186; 26 Mar 86 0:34 BST
Date: Tue, 25 Mar 86 17:10:16 GMT
From: Andy Cheese <abc%computer-science.nottingham.ac.uk@cs.ucl.ac.uk>
To: scheme@mc.lcs.mit.edu
Subject: Scheme wanted
Sender: abc%computer-science.nottingham.ac.uk@cs.ucl.ac.uk
Unfortunately for me and many of my colleagues the file dist.tar sitting
at prep.ai.mit.edu is much to big to anonymous ftp across the atlantic all
in one go, it breaks down half way thro usually. could somebody arrange to
have it split into manageable chunks or mail it to me and i'll act as a
distribution site for the uk.
Andy Cheese
Department of Computer Science
University of Nottingham
University Park
Nottingham
NG7 2RD
England
abc@uk.ac.nott.cs
abc@uk.ac.nott.cs@uk.ac.ucl.cs
∂26-Mar-86 0717 JAR@MC.LCS.MIT.EDU small changes
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 26 Mar 86 07:17:01 PST
Date: Wed, 26 Mar 86 10:18:56 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: small changes
To: dyb%indiana.csnet@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Mon 24 Mar 86 16:28:58 est from Kent Dybvig <dyb%indiana.csnet at CSNET-RELAY.ARPA>
Message-ID: <[MC.LCS.MIT.EDU].862337.860326.JAR>
Date: Mon, 24 Mar 86 16:28:58 est
From: Kent Dybvig <dyb%indiana.csnet at CSNET-RELAY.ARPA>
I have the same problem with people who, in Lisp, use upper case in
some places and lower case in others and mean the same identifier.
...
The right time to talk about this would have been a year and a half ago.
We made a decision at Brandeis and I don't see any evidence that there
is or might be general interest in reconsidering it.
∂26-Mar-86 1319 JAR@MC.LCS.MIT.EDU another nit
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 26 Mar 86 13:19:14 PST
Date: Wed, 26 Mar 86 16:20:58 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: another nit
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].862701.860326.JAR>
Now I'm trying to explain that QUOTE is allowed to return immutable
structured objects, and that particular implementations may have other
ways to create immutable data. One thing that implementations can do as
a result of this is "coalesce" immutable structured objects the same way
that symbols are always coalesced and numbers sometimes are. So it may
be the case that (EQV? '(A) '(A)) returns true. So far so good.
I'm trying to describe EQV? and EQ? in terms of a "operational
equivalence", for which I think Ihave a fairly elegant definition. I
was ready to say that EQV? is the procedure which determines operational
equivalence [with a proviso allowing it to make an approximate judgement
in the case of procedures and continuations, as discussed previously],
and then realized that my documentation would imply that (EQV? '(A)
'(A)) would be REQUIRED to return true in those implementations which
disallowed SET-CAR! on quoted lists.
Questions:
1. Should we say that the (SET-CAR! '(A) 'B) is an error, rather than
that it is unspecified? [If some of you say it should never be an
error, I think you'll get into an argument.]
2. Should we require (EQV? '(A) '(A)) to return true in implementations
which forbid clobbering quoted structure (that would be all
implementations, if the answer to 1. is yes)? I like this because it
simplifies the documentation; I don't need to say anything about
immutable data.
It would be a shame to require implementations to be able to distinguish
mutable from immutable data AND require them to create immutable data.
That has serious implementation implications; I don't want to propose
that.
N. I have noticed that the manual isn't careful about distinguishing "is
an error" from "unspecified". Do people want me to try to make a clear
distinction between them, or is an unclear distinction sufficient?
Maybe talking about mutability is a bad idea if there aren't MUTABLE?
and IMMUTABLE? predicates.
If you think I'm totally confused and that there's a better way to think
about this, you're probably right. Tell me how.
Jonathan
∂26-Mar-86 1445 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU another nit
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 26 Mar 86 14:44:48 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 26 MAR 86 17:13:46 EST
Date: 26 Mar 1986 17:11 EST (Wed)
Message-ID: <JINX.12193870476.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: another nit
In-reply-to: Msg of 26 Mar 1986 16:20-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
1. Should we say that the (SET-CAR! '(A) 'B) is an error, rather than
that it is unspecified?
I sort of like that.
2. Should we require (EQV? '(A) '(A)) to return true in implementations
which forbid clobbering quoted structure (that would be all
implementations, if the answer to 1. is yes)?
Although it would be nice, it seems that it has serious implementation
consequences: either quoted structure is hash-consed (BTW, what happens
them to immutable parts of back-quoted structure?), or EQV? becomes
more expensive than it already is.
I think that it would be a good idea to make a distinction between
unspecified and "is an error".
∂26-Mar-86 2247 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU small changes
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 26 Mar 86 22:44:38 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 27 MAR 86 01:46:08 EST
Date: Thu, 27 Mar 1986 01:43 EST
Message-ID: <CPH.12193963751.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: small changes
In-reply-to: Msg of 23 Mar 1986 18:10-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
Date: Sunday, 23 March 1986 18:10-EST
From: Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
Incompatible change:
I'd like to change the meaning of (DEFINE (form var ...) body ...) so
that it's defined in terms of LAMBDA instead of NAMED-LAMBDA.
I don't like this, and would prefer that
(DEFINE (FOO BAR BAZ) ...)
expand into
(DEFINE FOO
(LETREC ((FOO (LAMBDA (BAR BAZ) ...)))
FOO))
this additional complication mostly to eliminate the need for either
REC or NAMED-LAMBDA.
My reasoning is that this semantics solves a classical problem: namely
that if FOO is self referential, then subsequent redefinition of the
variable FOO will cause the originally defined procedure to change its
behavior. In particular, suppose that the procedure value of FOO is
bound to the variable BAR, and then FOO is redefined to some
completely different value, say (just to be extreme) the number 3.
I claim (and I believe that there will be support for this claim) that
the INTENT of the author of such a self referential procedure was that
the name FOO refer to the procedure itself, not the binding of the
variable FOO. This is because the binding is normally assumed to be
fixed; interactive definitions are something that the language has
because we recognize the need for debugging and evolution of our
programs. And the more naive the user, the more confusing it will be
if the procedure FOO depends on the value of the variable FOO, rather
than meaning "self reference".
Now, the reason why everyone wants the meaning of DEFINE to avoid the
use of LETREC (or its special case NAMED-LAMBDA) is obvious: it is
simpler to explain to people who are learning the language. However,
I think that this is detrimental in the long run, because sooner or
later many of those students who learned the simpler DEFINE semantics
will get screwed by the fact that their intuition didn't match the
semantics. I feel that teaching this subtle point would not take much
effort. Furthermore it would illustrate an important concept in
language design: that semantics should interact with our intuitive and
esthetic concepts of how a language should behave.
∂27-Mar-86 0126 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Scheme BNF
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 27 Mar 86 01:26:31 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 27 MAR 86 03:30:34 EST
Date: Thu, 27 Mar 1986 03:27 EST
Message-ID: <CPH.12193982768.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: Scheme BNF
In-reply-to: Msg of 23 Mar 1986 20:38-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
Date: Sunday, 23 March 1986 20:38-EST
From: Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
- Shouldn't backquote work on vectors? If not, then what's the
rationale for making them work on lists and not vectors?
I think that the only reason for this is that the #(...) syntax for
vectors was originally self-evaluating, which implied that the
contents of the vector was already quoted. If this requirement is
flushed (I don't know if there is consensus for this, but I would like
it to be), then I think that backquote should work on vectors also.
- What kinds of constants should be allowed in CASE clauses? I
don't really care, but I can imagine two possible answers:
1. If EQV? is used for comparisons, then it doesn't make any sense
to allow strings, lists, or vectors.
2. Use EQUAL? for comparisons, and allow any <datum>.
...but I won't listen to anyone who doesn't
supply a better word to use for the nonterminal than "casable".
I suspect that "casable" should be spelled "caseable". I don't think
that counts as a better word, but I hope that you'll read my comments
anyway. (Otherwise I suppose I'll have to invent a new language so
that someone will listen to me.)
A fine point I would like to make is that RRRS is careful to allow the
possibility of immutable strings. In this case I think that EQV?
makes sense on strings, so that (sigh) an even more complicated syntax
would be needed which took into account that possibility.
On the other hand, I like the idea of using EQUAL? and I agree that it
is easy to make efficient.
However, just to complicate things, I'll mention something about CASE
that has bothered me when I have tried to use it. I sometimes have
found that I am doing something of this kind:
(COND ((EQ? X 'FOO) ...)
((EQ? X BAR) ...)
((EQ? X 'BAZ) ...)
...)
where one of the keywords I am matching against has been parameterized
for one reason or another, and this forces me to use COND rather than
CASE. Has anyone else run into this problem? Is it interesting
enough to consider modifying CASE?
- I definitely want like to flush the (<var>) syntax for iteration
specs in DO. It is inconsistent for DO to have this alternate
form and not LET, and I don't like either. Does anyone actually
ever use it?
Actually, MIT Scheme has a consistent meaning for both of these, which
is that the variable in question is bound but not assigned. Such
variables are only useful in the presence of assignments, and it is an
error to refer to one between the time that it is bound and when it is
assigned. I suspect that some will find this offensive, although
personally I find it preferable to other alternatives that I have seen
for describing this particular state. So I'm just pointing it out for
general interest.
∂27-Mar-86 1142 JAR@MC.LCS.MIT.EDU Scheme BNF
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 27 Mar 86 11:39:55 PST
Date: Thu, 27 Mar 86 14:41:42 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: Scheme BNF
To: CPH@OZ.AI.MIT.EDU
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Thu 27 Mar 1986 03:27 EST from CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].863725.860327.JAR>
Date: Thu, 27 Mar 1986 03:27 EST
From: CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU
A fine point I would like to make is that RRRS is careful to allow the
possibility of immutable strings. In this case I think that EQV?
makes sense on strings, so that (sigh) an even more complicated syntax
would be needed which took into account that possibility.
I agree with you, but there are further ramifications. People have said
that EQ? and EQV? should agree on everything besides numbers and
characters. If this constraint is maintained, than EQ? must also return
true for immutable strings with identical contents. But this could make
EQ? expensive, which, it seems to me, would defeat the point of making
it different from EQV?. Another issue is whether EQV? should compare
immutable data in general. I would say it should. I guess I would
propose for EQ? to act on immutable data the same way it does on
procedures, remembering where they came from but maybe returning false
for things that are operationally equivalent. EQV? would test for true
operational equivalence in the case of immutable data.
On the other hand, I like the idea of using EQUAL? and I agree that it
is easy to make efficient.
Like I say, I don't care.
However, just to complicate things, I'll mention something about CASE
that has bothered me when I have tried to use it. I sometimes have
found that I am doing something of this kind:
(COND ((EQ? X 'FOO) ...)
((EQ? X BAR) ...)
((EQ? X 'BAZ) ...)
...)
where one of the keywords I am matching against has been parameterized
for one reason or another, and this forces me to use COND rather than
CASE. Has anyone else run into this problem? Is it interesting
enough to consider modifying CASE?
Yes. No. I like the fact that CASE is minimal. I think that if we try
to generalize it or come up with other constructs, we'll never be able
to agree on what to do, and the manual will get longer. I say you
should either use COND, a more featureful language than Scheme.
Actually, MIT Scheme has a consistent meaning for both of these, which
is that the variable in question is bound but not assigned. Such
variables are only useful in the presence of assignments, and it is an
error to refer to one between the time that it is bound and when it is
assigned. I suspect that some will find this offensive, although
personally I find it preferable to other alternatives that I have seen
for describing this particular state. So I'm just pointing it out for
general interest.
This is what T does too, although it doesn't detect the error. What do
other people think? This would have to be a new documented feature of
LET; would it have to be essential?
∂27-Mar-86 1242 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Scheme BNF
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 27 Mar 86 12:31:11 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 27 MAR 86 15:27:39 EST
Date: 27 Mar 1986 14:59 EST (Thu)
Message-ID: <JINX.12194108624.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU, RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: Scheme BNF
In-reply-to: Msg of 27 Mar 1986 14:41-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
MIT Scheme detects the bound but not assigned error only in
interpreted code currently.
I don't think that (let ((var)) ...) or the equivalent DO form have
to be in the standard. Both MIT Scheme and T (and whoever else wants
it) can implement them as a compatible extension.
∂27-Mar-86 1319 JAR@MC.LCS.MIT.EDU meaning of local define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 27 Mar 86 12:39:05 PST
Date: Thu, 27 Mar 86 15:40:53 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: meaning of local define
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].863786.860327.JAR>
LETREC may evaluate the right-hand sides in any order it pleases. But
one could expect for several reasons that local DEFINEs are evaluated
left to right (or top to bottom, depending on where the line breaks
are). The conjunction of these properties is in contradiction with the
assertion that local DEFINE's can always turn into a LETREC.
This can make a difference when a user tries to figure out whether
expressions like the following will return a well-defined result:
(define (foo x)
(define bar (1+ x))
(define baz (* bar bar))
(/ baz 6))
According to the documentation of DEFINE, this is equivalent to
(define (foo x)
(letrec ((bar (1+ x))
(baz (* bar bar)))
(/ baz 6)))
I'm not a big fan of local define's, but I think that if they are
implemented, they should have right-to-left semantics. I believe
local-DEFINE partisans will agree with this.
One solution is to introduce a new special form LETREC* which evaluates
the right-hand sides from top to bottom, and explain local DEFINE's in
terms of that. So the example would be equivalent to:
(define (foo x)
(letrec* ((bar (1+ x))
(baz (* bar bar)))
(/ baz 6)))
But LETREC* would otherwise be of very marginal usefulness, and we don't
need more secial forms.
So what I propose to do is to document the (LET ((var) ...) ...) and
(DO ((var) ...)...) syntax, with the meaning CPH described, and explain
local DEFINE's in terms of LET and SET!, mentioning that in the case
that the right-hand sides of all the DEFINE's are all LAMBDA's, the
LETREC expansion would work just as well. Sorry to reverse my former
opposition to this feature, but I hadn't thought of this before.
Opinions? Any ideas about other ways to describe DEFINE?
The funny thing about (LET ((var)) ...) is that it's the only documented
way to get a variable bound to an uninitialized location which it is an
error to access. This means that the correspondence between (LET ...)
and ((LAMBDA ...) ...) isn't as direct as it ought to be, since there's
no way that it can be an error to refer to a variable bound by a
LAMBDA-expression. LET is primitive in Common Lisp (for other reasons),
and I never liked that. On the other hand, this would give us an
opportunity to describe LETREC in terms of LET and SET! (exercise for
the student: how to make sure that the rhs's are evaluated in an
indeterminate order?). I sniff another special form and semantic
complexity here. What to do?
Jonathan.
∂27-Mar-86 1434 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA small changes
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 27 Mar 86 14:31:07 PST
Received: from THINK-AQUINAS.ARPA by MC.LCS.MIT.EDU 27 Mar 86 17:32:42 EST
Received: from THINK-KATHERINE.ARPA by THINK-AQUINAS.ARPA via CHAOS with CHAOS-MAIL id 17619; Thu 27-Mar-86 17:33:22-EST
Date: Thu, 27 Mar 86 17:32 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: small changes
To: CPH%OZ.AI.MIT.EDU@MIT-XX.ARPA, JAR@MIT-MC.ARPA
cc: RRRS-AUTHORS@MIT-MC.ARPA, gls@THINK-AQUINAS.ARPA
In-Reply-To: <CPH.12193963751.BABYL@MIT-OZ>
Message-ID: <860327173232.2.GLS@THINK-KATHERINE.ARPA>
Date: Thu, 27 Mar 1986 01:43 EST
From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
Date: Sunday, 23 March 1986 18:10-EST
From: Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
Incompatible change:
I'd like to change the meaning of (DEFINE (form var ...) body ...) so
that it's defined in terms of LAMBDA instead of NAMED-LAMBDA.
I don't like this, and would prefer that
(DEFINE (FOO BAR BAZ) ...)
expand into
(DEFINE FOO
(LETREC ((FOO (LAMBDA (BAR BAZ) ...)))
FOO))
this additional complication mostly to eliminate the need for either
REC or NAMED-LAMBDA.
...
I claim (and I believe that there will be support for this claim) that
the INTENT of the author of such a self referential procedure was that
the name FOO refer to the procedure itself, not the binding of the
variable FOO. This is because the binding is normally assumed to be
fixed; ...
Well, what about tracing utilities of the style that replace the
(functional) value of a variable with a new function that does tracing
and also calls the old value? I suppose I can always write
(DEFINE FOO (LAMBDA (BAR BAZ) ...))
but it seems to me the language is more transparent if not too many
implicit hidden things creep in. (In retrospect, I think that the
Common Lisp "feature" of DEFUN supplying an implicit named BLOCK
around its body was perhaps a mistake.)
--Guy
∂27-Mar-86 1436 JAR@MC.LCS.MIT.EDU meaning of local define (tiny correction)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 27 Mar 86 14:36:18 PST
Date: Thu, 27 Mar 86 17:38:06 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: meaning of local define (tiny correction)
To: JAR@MC.LCS.MIT.EDU
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Thu 27 Mar 86 15:40:53 EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
Message-ID: <[MC.LCS.MIT.EDU].863925.860327.JAR>
I meant to say left-to-right, not right-to-left.
∂27-Mar-86 1450 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA meaning of local define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 27 Mar 86 14:44:48 PST
Received: from THINK-AQUINAS.ARPA by MC.LCS.MIT.EDU 27 Mar 86 17:46:41 EST
Received: from THINK-KATHERINE.ARPA by THINK-AQUINAS.ARPA via CHAOS with CHAOS-MAIL id 17625; Thu 27-Mar-86 17:47:35-EST
Date: Thu, 27 Mar 86 17:46 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: meaning of local define
To: JAR@MIT-MC.ARPA, RRRS-AUTHORS@MIT-MC.ARPA
cc: gls@THINK-AQUINAS.ARPA
In-Reply-To: <[MC.LCS.MIT.EDU].863786.860327.JAR>
Message-ID: <860327174644.4.GLS@THINK-KATHERINE.ARPA>
Date: Thu, 27 Mar 86 15:40:53 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
LETREC may evaluate the right-hand sides in any order it pleases. But
one could expect for several reasons that local DEFINEs are evaluated
left to right (or top to bottom, depending on where the line breaks
----↑↑↑↑↑↑↑↑↑↑↑↑↑
are). The conjunction of these properties is in contradiction with the
assertion that local DEFINE's can always turn into a LETREC.
...
I'm not a big fan of local define's, but I think that if they are
implemented, they should have right-to-left semantics. I believe
----------------------------------↑↑↑↑↑↑↑↑↑↑↑↑↑
local-DEFINE partisans will agree with this....
Should the second indicated place read "left-to-right", or am I
misunderstanding your intent?
--Guy
∂27-Mar-86 1736 @MC.LCS.MIT.EDU:adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA NAMED-LAMBDA, REC, DEFINE
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 27 Mar 86 17:36:20 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 27 Mar 86 20:38:12 EST
Received: from tektronix by csnet-relay.csnet id ao16995; 27 Mar 86 18:47 EST
Received: by tektronix (5.31/5.14)
id AA18725; Thu, 27 Mar 86 11:40:20 PST
Received: by tekchips (5.31/5.14)
id AA15499; Thu, 27 Mar 86 11:42:42 PST
Message-Id: <8603271942.AA15499@tekchips>
To: rrrs-authors@mc.lcs.mit.edu
Cc: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
Subject: NAMED-LAMBDA, REC, DEFINE
Date: 27 Mar 86 11:42:37 PST (Thu)
From: adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
In the spirit of fanatic minimalism, I would prefer to
remove both NAMED-LAMBDA and REC.
From: Chris Hanson
Re: prefering LETREC in the expansion of (DEFINE (FOO ...) ...)
I claim (and I believe that there will be support for this claim) that
the INTENT of the author of such a self referential procedure was that
the name FOO refer to the procedure itself, not the binding of the
variable FOO. This is because the binding is normally assumed to be
fixed; interactive definitions are something that the language has
because we recognize the need for debugging and evolution of our
programs.
I agree (except that I think of redefinition as provided by the
development environment, not the language).
And the more naive the user, the more confusing it will be
if the procedure FOO depends on the value of the variable FOO, rather
than meaning "self reference".
I am not convinced that introducing self references behind the naive user's
back is doing him or her a great service. LETREC-introducing DEFINE
provides what you consider to be the intuitive behavior only in the simple
case. E.g.:
(DEFINE (FOO N) ...(FOO...)...)
(SET! BAZ FOO)
<subsequent redefinition of FOO>
the value of BAZ will be "consistent" because BAZ is the old version of
FOO, and the old version of FOO will recur by calling the old version.
But, in this case:
(DEFINE (FOO N) ... (BAR N) ...)
(DEFINE (BAR N) ... (FOO N) ...)
(SET! BAZ FOO)
<subsequent redefinition of FOO and BAR>
the value of BAZ will be inconsistent because the old version of FOO will
call the new version of BAR, which will call the new version of FOO.
Of course, a novice can still achieve confusion when defining and
redefining procedures using the simple DEFINE syntax. Furthermore, you
have to explain the difference between variable references that are self
references and those that are not.
∂27-Mar-86 1740 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: another nit
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 27 Mar 86 17:39:17 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 27 Mar 86 20:38:12 EST
Received: from tektronix by csnet-relay.csnet id ap16995; 27 Mar 86 18:48 EST
Received: by tektronix (5.31/5.14)
id AA18938; Thu, 27 Mar 86 11:59:07 PST
Received: by tekchips (5.31/5.14)
id AA15777; Thu, 27 Mar 86 12:01:20 PST
Message-Id: <8603272001.AA15777@tekchips>
To: JAR@mc.lcs.mit.edu
Cc: RRRS-AUTHORS@mc.lcs.mit.edu,
willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
Subject: Re: another nit
In-Reply-To: Your message of Wed, 26 Mar 86 16:20:58 EST.
<[MC.LCS.MIT.EDU].862701.860326.JAR>
Date: 27 Mar 86 12:01:15 PST (Thu)
From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
Leibniz's definition of the identity of X and Y goes something like this:
X = Y iff for all properties P, P(X) = P(Y)
If X and Y are identical except for the fact that EQV? or EQ? can
distinguish them, then they're not identical. Hence I don't see why
implementations that disallowed SET-CAR! on quoted lists would be
required to say that (EQV? '(A) '(A)) is #!true.
With the current semantics of EQ? and EQV?, I don't believe there's
any hope for an implementation-independent description. I'm sorry.
Yes, it should be an error to clobber quoted structure. In the formal
semantics I use, however, it's simpler to allow side effects. (I don't
want to have to deal with a separate class of immutable structures.)
No, (EQV? '(A) '(A)) should not be required to return true in implementations
that forbid clobbering quoted structure. If it were, (EQV? X Y) would have
to return true if X were a list that was quoted in file "foo" and Y were a
list that was quoted in file "bar". I don't want to write a fasl loader that
interns structures.
The manual should distinguish "is an error" from "unspecified", but you
shouldn't agonize over any unclear cases. I'm sorry about my mistakes.
Peace, Will
∂27-Mar-86 1825 JAR@MC.LCS.MIT.EDU another nit
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 27 Mar 86 18:25:06 PST
Date: Thu, 27 Mar 86 21:26:53 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: another nit
To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of 27 Mar 86 12:01:15 PST (Thu) from willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
Message-ID: <[MC.LCS.MIT.EDU].864078.860327.JAR>
Date: 27 Mar 86 12:01:15 PST (Thu)
From: willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
Leibniz's definition of the identity of X and Y goes something like this:
X = Y iff for all properties P, P(X) = P(Y)
If X and Y are identical except for the fact that EQV? or EQ? can
distinguish them, then they're not identical. Hence I don't see why
implementations that disallowed SET-CAR! on quoted lists would be
required to say that (EQV? '(A) '(A)) is #!true.
Well, let Z be some object, and let P be the property of objects X for
which X = Z. Then your definition won't work, because it will be
circular. So we make sure that = doesn't occur in P, and we win.
That's how I define operational equivalence: let's write X = Y when X is
operationally equivalent to Y; I say X = Y iff for all programs P not
involving = (i.e. EQ?, EQV?, MEMQ, etc.), the value and effects of P(X)
are the same as the value and effects of P(Y).
Now = isn't computable, so we define EQV? to be an approximation to =
which in the case of = procedures might return false but will return
true in the cases that Sussman wants it to. So EQV? is a computable
approximation to =.
But by this definition, if it's an error to alter quoted structure, then
necessarily (eqv? '(a) '(a)). Thus my inquiry.
[I guess this begs the question of what "the same as" means, but I think
the definition can be made to work.]
With the current semantics of EQ? and EQV?, I don't believe there's
any hope for an implementation-independent description. I'm sorry.
I agree that EQV? can't be made to work the same in all implementations,
but I think my description captures something reasonable. I should have
been more explicit before.
Yes, it should be an error to clobber quoted structure. In the formal
semantics I use, however, it's simpler to allow side effects. (I don't
want to have to deal with a separate class of immutable structures.)
No, (EQV? '(A) '(A)) should not be required to return true in implementations
that forbid clobbering quoted structure. If it were, (EQV? X Y) would have
to return true if X were a list that was quoted in file "foo" and Y were a
list that was quoted in file "bar". I don't want to write a fasl loader that
interns structures.
Not so - if EQV? had a way to distinguish mutable from immutable data,
it could do exactly what it does with large numbers - a
non-constant-time comparison, similar what EQUAL? does. No interning
necessary, but either extra type codes or a disjoint region of memory in
order to be able to tell when it should do a pointer omparison and when
to look at the components.
Jonathan
∂28-Mar-86 0706 @MC.LCS.MIT.EDU:duke@mitre.ARPA A bug in my version of MIT Scheme
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 28 Mar 86 07:04:32 PST
Received: from mitre.ARPA by MC.LCS.MIT.EDU 28 Mar 86 10:05:15 EST
Full-Name: DUKE BRISCOE
Message-Id: <8603281504.AA07255@mitre.ARPA>
Organization: The MITRE Corp., Washington, D.C.
To: scheme@mc.lcs.mit.edu
Cc: duke@mitre.ARPA
Subject: A bug in my version of MIT Scheme
Date: Fri, 28 Mar 86 10:04:24 -0500
From: Duke Briscoe <duke@mitre.ARPA>
We have found a bug in the multiplication, *, procedure of our version of
Scheme. The deeper root of the problem is apparently in the primitive for
multiplying fixnums. Multiplying 0 times a negative number results in
#[(undefined-type-code 81) 0] . It is easy enough to work around this, but
someone maintaining MIT Scheme might look into this if it hasn't already
been fixed. The version we're using is the VAX/VMS version of MIT Scheme,
Microcode 6.1, Runtime 11.2, Features 1.1, Student 11.1, and is dated
Thursday May 31, 1985.
∂28-Mar-86 0835 NET-ORIGIN@MC.LCS.MIT.EDU self-reference and DEFINE
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 28 Mar 86 08:32:53 PST
Received: from ZERMATT.LCS.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 28 MAR 86 11:34:32 EST
Received: from ASPEN.LCS.MIT.EDU by MIT-ZERMATT.ARPA via CHAOS with CHAOS-MAIL id 29416; Fri 28-Mar-86 11:33:55-EST
Date: Fri, 28 Mar 86 11:33 EST
From: Robert Halstead <rhh@MIT-VAX.ARPA>
Subject: self-reference and DEFINE
To: RRRS-AUTHORS@MIT-MC.ARPA
In-Reply-To: <860327173232.2.GLS@THINK-KATHERINE.ARPA>
Message-ID: <860328113321.1.RHH@ASPEN.LCS.MIT.EDU>
I agree with the people who aren't ecstatic about the implicit
self-reference of (DEFINE (FOO BAR BAZ) ...) -- mainly because of the
fact that it works smoothly for recursive definitions but not for
mutually recursive ones, as pointed out by Adams at Tektronix, but also
because of the introduction of gratuitous hidden stuff. Too many times,
I've seen people who thought they understood the simple Scheme model of
environments (and did!) confuse themselves by trying experiments where
they rebind a function name and then wonder why the re-binding didn't
"take" in all the places they would have expected. It is then necessary
to explain that reality is a little more complicated, and that their
experiment didn't work because of some nice things Scheme is trying to
do for you without telling you.
I also doubt that as a practical, software engineering matter, in the
hands of experienced users, it matters very much whether DEFINE does its
special self-referential legerdemain or not! But I've never been able
to change any minds with these arguments, and I wonder whether we should
be trying to change this aspect of the MIT Scheme design at this point
in the game. -Bert
∂28-Mar-86 1319 @MC.LCS.MIT.EDU:LS.JINX@DEEP-THOUGHT.MIT.EDU meaning of local define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 28 Mar 86 13:17:32 PST
Received: from DEEP-THOUGHT.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 28 MAR 86 16:18:29 EST
Date: 28 Mar 1986 16:17 EST (Fri)
Message-ID: <LS.JINX.12194385065.BABYL@MIT-EECS>
From: Bill Rozas <LS.JINX@DEEP-THOUGHT.MIT.EDU>
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: meaning of local define
In-reply-to: Msg of 27 Mar 1986 15:40-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
My thoughts about local DEFINE and RECless DEFINE:
1) I think that local DEFINEs should be EXACTLY equivalent to LETREC.
I also think that the standard should ONLY support LAMBDA expressions
in LETREC, thus
(define (foo x) ; (1)
(define bar (1+ x))
(define baz (* bar bar))
(/ baz 6))
would be unspecified (might be an error in some implementations), and
so would
(letrec ((a (cons 3 (lambda () a)))) ; (2)
a)
and similar things.
Individual implementations may extend the semantics of LETREC and
local DEFINE, but it is up to them to give a consistent semantics.
I REALLY dislike expressions of type (2) above because they are very
misleading, and dislike expressions of type (1) almost as much.
Note that I am a partisan of local DEFINE. I also think (from
previous discussions) that most people at MIT would accept
this. We've agreed on it before but never enforced it on MIT Scheme.
2) I think that DEFINE should not have an implicit NAMED-LAMBDA. I
think that naive users will get confused either way (in equal
numbers), and thus the decision should be left to us.
At MIT, DEFINE behaves differently on the Scheme system on which S&ICP
is run (we call this the student system) from the one which we use
(which we call the development system). The student system always
uses the semantics implied by the interpreter in section 4.1 of S&ICP
(as opposed to the LETREC definition). We call this semantics
"incremental" DEFINE, rather than "local" or "internal" DEFINE. I
have not seen a single person have any problems when transferring from
the student system to the development system (most of our hackers,
including myself, transferred at one point from one to the other), so
this incompatibility is not very important in practice.
Thus my suggestion to CPH, JMILLER, and other people at MIT concerned
about naive users, is that we keep these differences (implicit
NAMED-LAMBDA vs. LAMBDA, incremental vs. local DEFINE) in semantics
between both systems, but the standard should be cleaner.
Note: for the difference between both semantics for DEFINE, read
section 5.2.5 of S&ICP. In particular, read exercise 5.27. The
student system at MIT would return 16, the development system would
signal an error. Again, I do not remember seeing users run into this
difference when transferring from one system to the other, because
good style dictates that all internal definitions be used for defining
procedures only, and it is this restriction that I would like to place
on the standard.
∂29-Mar-86 1326 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Scheme BNF
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Mar 86 13:26:21 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 29 MAR 86 16:27:58 EST
Date: Sat, 29 Mar 1986 16:27 EST
Message-ID: <CPH.12194649017.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: Scheme BNF
In-reply-to: Msg of 27 Mar 1986 14:41-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
Date: Thursday, 27 March 1986 14:41-EST
From: Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
I guess I would propose for EQ? to act on immutable data the same
way it does on procedures, remembering where they came from but
maybe returning false for things that are operationally
equivalent. EQV? would test for true operational equivalence in
the case of immutable data.
I think that this is a good idea. If strings are immutable, I don't
see why EQ? should be required to compare their contents.
∂29-Mar-86 1343 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU meaning of local define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Mar 86 13:43:40 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 29 MAR 86 16:45:23 EST
Date: Sat, 29 Mar 1986 16:45 EST
Message-ID: <CPH.12194652195.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: meaning of local define
In-reply-to: Msg of 27 Mar 1986 15:40-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
Date: Thursday, 27 March 1986 15:40-EST
From: Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
This can make a difference when a user tries to figure out whether
expressions like the following will return a well-defined result:
(define (foo x)
(define bar (1+ x))
(define baz (* bar bar))
(/ baz 6))
According to the documentation of DEFINE, this is equivalent to
(define (foo x)
(letrec ((bar (1+ x))
(baz (* bar bar)))
(/ baz 6)))
I'm not a big fan of local define's, but I think that if they are
implemented, they should have right-to-left semantics. I believe
local-DEFINE partisans will agree with this.
I (sort of) like local-DEFINE. If I understand correctly, you would
like to have them be evaluated sequentially because each appears,
syntactically, to be a side-effect. I feel funny about this, because
the example above is precisely the kind of thing that constantly
screws up beginning users in 6.001.
I'm used to thinking of local-DEFINE as a syntax for LETREC (which
takes less horizontal space!), and not having any dependence on order
of evaluation. And in fact I consider that very, very bad style.
The example above should be written using LET.
In fact, the only useful values in local-DEFINE or LETREC are
procedure definitions and delayed evaluations, because nothing else
can need the mutual recursion -- every other kind of expression can
always be written using LET.
Anyway, to get to the point: as I recall, local-DEFINE was included in
the standard only because of S&ICP. I would favor leaving the current
description of its semantics, perhaps with a prominent note to that
effect, and recommending LETREC for new code.
I should probably learn to use LETREC instead, but I fear I'm too
attached to DEFINE by now.
∂29-Mar-86 1346 JAR@MC.LCS.MIT.EDU small changes
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Mar 86 13:46:04 PST
Date: Sat, 29 Mar 86 16:48:01 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: small changes
To: dyb%indiana.csnet@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].865699.860329.JAR>
Date: Mon, 24 Mar 86 10:13:39 est
From: Kent Dybvig <dyb%indiana.csnet at CSNET-RELAY.ARPA>
I would like to see the Common Lispy definition that anything with no
other possible syntax (especially wrt numbers) is an identifier. I don't
necessarily like it, but I see no reason to do otherwise, and I might
be interested sometime in implementing Common Lisp in Scheme.
There were some objections to this at the Brandeis meeting; it's nice to
be able to catch typos in numbers, knowing from the first character that
what's coming is a symbol makes for simpler readers, and the "everything
except" definition can't be captured by a context-free grammar. But
regardless of the reasons, there wasn't agreement on allowing anything
but what's there, so as usual this made the language smaller than some
people would have liked, but it includes the things that everyone could
accept.
If you want to do Common Lisp in Scheme, this will be the least of your
problems. You'll need to be able to deal with many other extensions to
the read syntax, including package prefixes, escape sequences, circular
structure, and a zillion other things.
- I don't know of anyone who is a NAMED-LAMBDA partisan, so I intend to
flush it. (It's not essential, anyhow.) However, I know there are some
people out there who are partial to REC, so I'll take the conservative
position again and leave it in (even though I and other MIT folks don't
like it).
Thank you for leaving in REC. I could not live without it.
I forgot that Jim Miller wanted NAMED-LAMBDA, and Henry Wu also spoke up
later in support of it, so it stays. I should have insisted on the
things that I can't live without at the Brandeis meeting instead of
being a nice guy. As it is I can't stand to program in RRRS Scheme.
But that's beside the point.
I've forgotten what the non-controversial changes to DO are. Perhaps
you could refresh my memory. I hope it was related to the implied use of
set! in the description used in the manual.
That's correct.
I would also like to bring up the case insensitivity issue once again.
Yes, I do prefer that A-Symbol and a-symbol be different. I like to use
case to set off certain things, like X for set and x for the element in
(member x X). I see no value in having case-insensitive symbols, and
a lot of conversion trouble. I think most of us now have terminals with
lower-case letters. I would like the special-form keywords and function
names to be in lower case.
Sorry about my previous reply. I just meant to say that I have never
heard a case-sensitivity argument on either side of the issue which
wasn't basically religious. I don't think the two sides will ever be
able to speak to each other dispassionately. I have been on both sides
of the question at various times myself. (I think I started to change
my mind when I tried to explain to my father, a computer novice, what a
fantastically liberating thing it was that Foo and fOO were different,
and he thought I had taken leave of my senses.)
The purely political arguments for case-insensitivity are: conservatism
- don't change the report more than necessary - we had a chance a year
ago to talk about this, why bring it up now; compatibility with T, MIT
Scheme, PC Scheme, MacScheme, and many others; and compatibility with
Common Lisp and most operating systems (other than Unix and Multics) and
languages (other than C).
If you insist on going counter to the Brandeis decision, making your
implementation and book case-sensitive, then there will be some painful
decisions to make about what to say in the report. The report will have
to say that some implementations of Scheme are case-sensitive; as for
what to do with upper case, I can think of two solutions:
1. It's OK to write it, but only programs (and data files) which don't
care one way or the other (using lower case for the things in the
manual, and don't depend on EITHER (eq? 'foo 'Foo) or (not (eq? 'foo
'Foo))), will be portable.
2. Say that only programs which use lower-case only will be portable.
I would even be willing to say that SYMBOL->STRING will return lower
case, and STRING->SYMBOL will only be guaranteed to accept lower-case
letters. Implementations could be permitted to do what they like, even
signal an error, if there are upper-case letters. (Case-insensitivity
advocates should note that this makes no statement about how print names
are to be stored internally, although these particular procedures would
presumably be a little more efficient if the internal case of portable
identifiers was lower.)
I'm not sure how much it matters much which case WRITE and DISPLAY
generate, but there will be no agreement on this, so we can just make a
note that what these things do is implementation-dependent, but
case-sensitive implementations will print lower case so that READ will
work. I think this can only cause problems if you're FTP'ing between an
insensitive implementation which prints upper case to a case sensitive
implementation, but it seems to me that this problem is politically
unsolvable if you will not agree to be case-insensitive.
There will be problems if you actually exploit case sensitivity in your
book, that is, if any program depends on the non-eq-ness of two
identifiers with the same name in differing cases. Then your book will
conflict with most implementations. If you use varying case but never
depend on (not (eq? 'foo 'Foo)) then everything should be fine.
PLEASE - if people want to discuss this question - keep in mind the
political situation; remember that if you like case-sensitivity or
case-insensitivity, there's no chance you'll make a convert of someone
in the opposite camp, so don't inflict pain by arguing this question.
Be nice. The real question is what concessions are we willing to make
in order to come to a consensus. I have stated above how far I'll go.
On one other issue, there are some of us here at IU who have serious
difficulty with #!true and #!false, and we will be sending out a new
proposal under separate cover in a day or so.
I agree completely; I have always thought that #!true and #!false were
incredibly ugly, and I argued against them at Brandeis. And I have
heard at least four different people say the same thing to me in the
past couple of days alone. T uses #T and #F (or #t and #f), inspired by
3-Lisp's $T and $F. Who doesn't like #T and #F besides people at MIT
(with whom I can speak in person)? Why?
Jonathan
∂29-Mar-86 1350 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU small changes
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Mar 86 13:49:56 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 29 MAR 86 16:47:58 EST
Date: Sat, 29 Mar 1986 16:47 EST
Message-ID: <CPH.12194652652.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
To: Guy Steele <gls@AQUINAS.THINK.COM>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: small changes
In-reply-to: Msg of 27 Mar 1986 17:32-EST from Guy Steele <gls at THINK-AQUINAS.ARPA>
Date: Thursday, 27 March 1986 17:32-EST
From: Guy Steele <gls at THINK-AQUINAS.ARPA>
Well, what about tracing utilities of the style that replace the
(functional) value of a variable with a new function that does tracing
and also calls the old value?
I think this could be fixed by having a somewhat more sophisticated
tracing procedure. But that is a good point.
∂29-Mar-86 1353 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU NAMED-LAMBDA, REC, DEFINE
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Mar 86 13:52:54 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 29 MAR 86 16:54:09 EST
Date: Sat, 29 Mar 1986 16:53 EST
Message-ID: <CPH.12194653644.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
To: adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
Cc: rrrs-authors@MC.LCS.MIT.EDU
Subject: NAMED-LAMBDA, REC, DEFINE
In-reply-to: Msg of 27 Mar 1986 14:42-EST from adams%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
Date: Thursday, 27 March 1986 14:42-EST
From: adams%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
Of course, a novice can still achieve confusion when defining and
redefining procedures using the simple DEFINE syntax.
Furthermore, you have to explain the difference between variable
references that are self references and those that are not.
I hadn't really thought that through. Clearly the situation with
DEFINE can become arbitrarily complex with either semantics.
So I would like to retract my earlier statement in support of the
simpler semantics.
∂29-Mar-86 1355 JAR@MC.LCS.MIT.EDU meaning of local define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Mar 86 13:55:36 PST
Date: Sat, 29 Mar 86 16:57:33 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: meaning of local define
To: CPH@OZ.AI.MIT.EDU
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Sat 29 Mar 1986 16:45 EST from CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].865709.860329.JAR>
Date: Sat, 29 Mar 1986 16:45 EST
From: CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU
Anyway, to get to the point: as I recall, local-DEFINE was included in
the standard only because of S&ICP. I would favor leaving the current
description of its semantics, perhaps with a prominent note to that
effect, and recommending LETREC for new code.
OK. I don't care much about this question. Since you and JINX are the
only people who have commented, I'll probably do as you say. Leaving it
the way it is would simplify the language & documentation, I think, but
a clarification is in order, since it's implicit that define's are like
evaluable expressions, and the bodies of LAMBDA's etc. are evaluated
sequentially. I also thought that local DEFINE's were supposed to be
"like top level ones," which are done sequentially; but the analogy
already breaks down because all local DEFINE's have to appear
contiguously at the front of the body.
My BNF, and the current RRRS, say that DEFINE's can't occur in BEGIN's;
does anyone have any problem with that? If so, what should it mean?
∂29-Mar-86 1405 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU meaning of local define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Mar 86 14:05:27 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 29 MAR 86 17:07:20 EST
Date: Sat, 29 Mar 1986 17:07 EST
Message-ID: <CPH.12194656203.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: meaning of local define
In-reply-to: Msg of 29 Mar 1986 16:57-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
Date: Saturday, 29 March 1986 16:57-EST
From: Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
My BNF, and the current RRRS, say that DEFINE's can't occur in
BEGIN's; does anyone have any problem with that? If so, what
should it mean?
I have a small problem with that: as always, it is necessary to be
able to write macros that expand into multiple definitions. So MIT
Scheme takes the position that a BEGIN appearing anywhere that a
DEFINE may appear is allowed to contain DEFINEs. This seems to solve
the problem perfectly adequately, and is very easy to implement.
∂29-Mar-86 1439 JAR@MC.LCS.MIT.EDU Scheme BNF
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Mar 86 14:39:40 PST
Date: Sat, 29 Mar 86 17:41:34 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: Scheme BNF
To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of 25 Mar 86 12:23:34 PST (Tue) from willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
Message-ID: <[MC.LCS.MIT.EDU].865763.860329.JAR>
Date: 25 Mar 86 12:23:34 PST (Tue)
From: willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
<[MC.LCS.MIT.EDU].860721.860324.JAR>
[Someone (Dybvig maybe?):]
Can we also have (BEGIN) return an unspecified value instead of
being invalid syntax?
[JAR:]
I am certainly opposed to this.
Care to say why?
I should have said more. COND is already complicated with an exception
because it says that if no guard returns true and there's no ELSE, then
the value is unspecified. People like this because it make COND work
well in statement positions where you don't care about the effect
anyhow. So, in consequence, (COND) makes sense, without having to say
explicitly that (COND) is legal. But in order to allow (BEGIN) to work,
we have to add an exception to the description "BEGIN evaluates the
forms sequentially, and returns the value of the last form" - you have
to say "...except that if there are no forms, the value is unspecified".
I have written interpreters and compilers that deal with (BEGIN) and
they always have an extra conditional in them to be able to deal with
that as a special case. And if I had written the BNF as (BEGIN
<statement>* <expression>), as I probably should have, that wouldn't
have worked. I guess you could make some of the same arguments here
that you do to allow (COND); programs which generate Scheme programs
might know that the thing they're generating is a list of statements to
be put in a statement position, so they might reasonably want to
generate (BEGIN). But I hate exceptions and unnecessary conditionals.
The COND exception seems unavoidable, and to disallow (COND) we'd need
an exception in the form of a rationale explaining why it was disallowed
even though its semantics is clear; but a (BEGIN) exception does seem
avoidable and unnecessary. I guess I don't care as much about this as I
thought I did.
By the way: (COND) and (CASE x) are not disallowed by the textual
description in the RRRS, they're only disallowed because the prototype
lines say (COND clause1 clause2 ...) instead of (COND clause1 ...). The
first means one or more, the second would mean zero or more.
Jonathan
∂29-Mar-86 1532 JAR@MC.LCS.MIT.EDU Scheme BNF
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Mar 86 15:31:54 PST
Date: Sat, 29 Mar 86 18:33:54 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: Scheme BNF
To: dyb%indiana.csnet@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].865782.860329.JAR>
Date: Mon, 24 Mar 86 10:39:14 est
From: Kent Dybvig <dyb%indiana.csnet at CSNET-RELAY.ARPA>
I think it should not work on vectors. It makes sense to me only in non-
constants, and until we make a firm statement that vectors have some useful
meaning in Scheme other than as constants, backquote should not work within
vectors. I also have some amount of hesitance about splicing a list into
a vector, etc., and what that would mean.
The RRRS doesn't say that backquote doesn't work on vectors; I'm only
suggesting a clarification. I assume it would work as described in RRRS
and as in Common Lisp, which is that the thing returned by form in ,@form
must be a list, whose elements are spliced into the vector.
I do not like the use of EQUAL?. If you don't like <casable>, how about
<atom>? Seriously, we need some term anyway, since it is the same thing
accepted by EQV?. What about <simple>? Or <tag>?
I'm trying to avoid introducing new nonterminals into the grammar, and
nothing fits; self-evaluating doesn't work, because strings are
self-evaluating and symbols aren't; there's already a <simple something
or other> for backquote, but it includes strings.
Also, it's been said before, but I think we should allow for the optional
syntax of a single "<casable>" not in a list.
<case clause> ::= (<datum> <sequence>)
This complicates the grammar, and (() <sequence>) is ambiguous. This
was discussed at Brandeis, and this version of case was accepted
unanimously after a somewhat painful discussion; I'm only trying to make
it more precise.
- Oh yeah, I forgot to mention in my previous message that I would like to
document DELAY and FORCE, as non-essential special form and procedure,
respectively. I believe they're non-controversial, and desirable given
that they have a central role in S&ICP and are a little tricky to
describe and implement.
If you don't mind, please send out your prose for these and include the
appropriate code for them. I don't have them in Chez Scheme yet and I'm
not in the mood to think.
There's a description and implementation in Structure & Interpretation.
I'll send out my prose with the rest of the manual next week.
I am uncomfortable with the use of <sequence> in light of the existence
of sequence as a special form.
Why? I chose the term precisely because the term "sequence" was already
in use this way. But I'll try to think of something better.
Furthermore, I think that <expression>+
would be more expressive where it appears, and in Scheme there should be
no confusion with the operator + or sign +.
The + meaning at least one won't be confused with + meaning the
character or identifier + because it will be in superscript and in Roman
typeface.
I was thinking of changing the definition of <sequence> to be
<statement>* <expression>, to be a little more descriptive, and to
emphasize the fact that the last value of a <sequence> becomes its
value. I think this nonterminal improves readability; if I were to get
rid of it I'd also want to dispose of <consequent> and several others.
Anyone else have an opinion?
Jonathan
∂29-Mar-86 1705 JAR@MC.LCS.MIT.EDU meaning of local define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Mar 86 17:05:23 PST
Date: Sat, 29 Mar 86 20:07:17 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: meaning of local define
To: CPH@OZ.AI.MIT.EDU
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Sat 29 Mar 1986 17:07 EST from CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].865830.860329.JAR>
Date: Sat, 29 Mar 1986 17:07 EST
From: CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU
Date: Saturday, 29 March 1986 16:57-EST
From: Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
My BNF, and the current RRRS, say that DEFINE's can't occur in
BEGIN's; does anyone have any problem with that? If so, what
should it mean?
I have a small problem with that: as always, it is necessary to be
able to write macros that expand into multiple definitions. So MIT
Scheme takes the position that a BEGIN appearing anywhere that a
DEFINE may appear is allowed to contain DEFINEs. This seems to solve
the problem perfectly adequately, and is very easy to implement.
Agreed, but it's also a compatible extension, presumably one added that
would be added when macros are, so it doesn't need to be documented.
Jonathan.
∂29-Mar-86 1718 JAR@MC.LCS.MIT.EDU NAMED-LAMBDA, REC, DEFINE
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Mar 86 17:18:02 PST
Date: Sat, 29 Mar 86 20:19:43 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: NAMED-LAMBDA, REC, DEFINE
To: CPH@OZ.AI.MIT.EDU
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU,
adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
In-reply-to: Msg of Sat 29 Mar 1986 16:53 EST from CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].865833.860329.JAR>
Date: Sat, 29 Mar 1986 16:53 EST
From: CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU
So I would like to retract my earlier statement in support of the
simpler semantics.
One man's simple is another's complex... could you be more precise?
Which one do you like now?
Alternative A (Norman's and mine and S&ICP's):
(define (foo . rest) . body)
means the same thing as
(define foo (lambda rest . body))
Alternative B (RRRS's and MIT Scheme's):
(define (foo . rest) . body)
means the same thing as
(define foo (letrec ((foo (lambda rest . body))) ;or any equivalent syntax
foo))
if foo is an identifier, and means the same as
(define foo (lambda rest . body))
if foo is of the form (bar . rest).
Alternative C:
<fill in the blank>
- Jonathan
∂29-Mar-86 2011 JAR@MC.LCS.MIT.EDU (EQV? '(A) '(A))
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Mar 86 20:11:45 PST
Date: Sat, 29 Mar 86 23:13:44 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: (EQV? '(A) '(A))
To: JINX@MC.LCS.MIT.EDU
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of 26 Mar 1986 17:11 EST (Wed) from Bill Rozas <JINX%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
Message-ID: <[MC.LCS.MIT.EDU].865944.860329.JAR>
Date: 26 Mar 1986 17:11 EST (Wed)
From: Bill Rozas <JINX%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
2. Should we require (EQV? '(A) '(A)) to return true in implementations
which forbid clobbering quoted structure (that would be all
implementations, if the answer to 1. is yes)?
Although it would be nice, it seems that it has serious implementation
consequences: either quoted structure is hash-consed (BTW, what happens
them to immutable parts of back-quoted structure?), or EQV? becomes
more expensive than it already is.
Why should non-constant-time behavior be desirable for numbers, but
desirable for lists? Immutable structured data with identical
components are "operationally identical", and I'm endeavoring to make
EQV? a close approximation to the operationally-identitical relation.
The backquoted structure question is a sticky one. Don't know quite
what to do about it.
∂29-Mar-86 2113 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU small changes
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Mar 86 21:13:40 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 30 MAR 86 00:15:31 EST
Date: 30 Mar 1986 00:15 EST (Sun)
Message-ID: <JINX.12194734081.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: dyb%indiana.csnet@CSNET-RELAY.ARPA, RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: small changes
In-reply-to: Msg of 29 Mar 1986 16:48-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
I don't mind #t #f (#T #F). I think that #!true and #!false are
merely long, not necessarily ugly.
I would even be willing to say that SYMBOL->STRING will return lower
case, and STRING->SYMBOL will only be guaranteed to accept lower-case
letters. Implementations could be permitted to do what they like, even
signal an error, if there are upper-case letters. (Case-insensitivity
advocates should note that this makes no statement about how print names
are to be stored internally, although these particular procedures would
presumably be a little more efficient if the internal case of portable
identifiers was lower.)
I would much rather have a procedure canonicalize-case which takes a
string in either case and converts it to the appropriate case. I do
not use symbol->string and string->symbol very often, and the extra
code to type does not seem like a real burden but would make
SYMBOL->STRING cheaper since it could always return the standard case
(rather than lower case). MIT Scheme unfortunately (I don't like it)
uses upper case internally, but SYMBOL->STRING is basically CAR.
Just a comment on my usual style: I write all my code in lower case,
but write quoted symbols in upper case. Thus they are more easily
distinguishable from identifiers (the quote is easy to miss
sometimes), yet I can conveniently type them in lower case (MIT Scheme
is insensitive).
For example, I would write
(define (definition? exp)
(and (pair? exp) (eq? 'DEFINE (car exp))))
Which would be true of
'(define (definition? exp)
(and (pair? exp) (eq? 'DEFINE (car exp))))
I rarely use mixed case in Scheme.
I don't mind #t #f (#T #F).
∂29-Mar-86 2122 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU meaning of local define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Mar 86 21:22:30 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 30 MAR 86 00:24:19 EST
Date: 30 Mar 1986 00:24 EST (Sun)
Message-ID: <JINX.12194735743.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU, RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: meaning of local define
In-reply-to: Msg of 29 Mar 1986 16:57-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
I also thought that local DEFINE's were supposed to be
"like top level ones," which are done sequentially
At some point in time (I don't remember what it currently does) MIT
Scheme collected top level defines and did them all at once (with
unassigned values, to detect use before the new value is assigned)
before running any code (the defines afterwards being treated as
assignments), thus treating top level define and local define similarly.
The only sequentiality inherent in top level define comes from
interaction, namely that some code can be run before all defines are
apparent. I don't view this as a difference between both.
My BNF, and the current RRRS, say that DEFINE's can't occur in BEGIN's;
The only problem is the same that originally gave us (progn 'compile
...) in MacLisp, namely macro expansion. Since we do not have macros
in the standard this is moot probably.
∂29-Mar-86 2147 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU (EQV? '(A) '(A))
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Mar 86 21:47:06 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 30 MAR 86 00:42:52 EST
Date: 30 Mar 1986 00:42 EST (Sun)
Message-ID: <JINX.12194739121.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: (EQV? '(A) '(A))
In-reply-to: Msg of 29 Mar 1986 23:13-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
Why should non-constant-time behavior be desirable for numbers, but
desirable for lists? Immutable structured data with identical
components are "operationally identical", and I'm endeavoring to make
EQV? a close approximation to the operationally-identitical relation.
As far as I know = always terminates and is rather efficient (linear
in the size of the numbers in bits?). You are suggesting that we make
EQV? work like EQUAL? on immutable lists, but this has a problem:
1) The fast, simple definition fails on circular structure. Agreed
that there is no way in the standard to have immutable circular
structure, but this seems like a simple compatible extension which
people might want to make. It would then be bad if EQV? were not to
terminate on immutable objects.
2) The only implementations of EQUAL? which handle circular structure
correctly that I know of are very expensive (much worse than linear).
This would make EQV? unusable in many cases, but we are trying to
encourage its use over EQ?.
I'm not saying I necessarily disagree with your suggestion, but I need
more time to think about it before I agree.
PS: If you have an efficient implementation of EQUAL? which handles
circular structure, I would appreciate your sending it to me.
∂30-Mar-86 0902 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU NAMED-LAMBDA, REC, DEFINE
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 30 Mar 86 09:02:14 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 30 MAR 86 11:56:44 EST
Date: Sun, 30 Mar 1986 11:53 EST
Message-ID: <CPH.12194861182.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: NAMED-LAMBDA, REC, DEFINE
In-reply-to: Msg of 29 Mar 1986 20:19-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
Date: Saturday, 29 March 1986 20:19-EST
From: Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
Date: Sat, 29 Mar 1986 16:53 EST
From: CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU
So I would like to retract my earlier statement in support of the
simpler semantics.
One man's simple is another's complex... could you be more precise?
Which one do you like now?
And the winner is...
Alternative A (Norman's and mine and S&ICP's):
(define (foo . rest) . body)
means the same thing as
(define foo (lambda rest . body))
∂30-Mar-86 1310 JAR@MC.LCS.MIT.EDU [dfried%indiana.csnet: boolean?]
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 30 Mar 86 13:10:08 PST
Date: Sun, 30 Mar 86 16:12:06 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: [dfried%indiana.csnet: boolean?]
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].866290.860330.JAR>
I have thought of suggesting the following feature, which T has and
which is nice to have occasionally, and is pleasantly symmetrical with
the other type predicates like NUMBER?, SYMBOL?, PAIR?, etc. I haven't
suggested it so far because of its marginal usefulness, but would be
happy to put it in if other people think it's a good idea. Opinions?
(Dan, I assume you meant #t instead of $t.)
- Jonathan
Date: Sun, 30 Mar 86 11:49:51 est
From: Dan Friedman <dfried%indiana.csnet at CSNET-RELAY.ARPA>
To: jar at mc.lcs.mit.edu
Re: boolean?
If # is used in the first position of the true and false
value, might I suggest the existence of a predicate
boolean? This predicate returns #t if its single argument
is #t or #f.
Dan
∂30-Mar-86 1347 JAR@MC.LCS.MIT.EDU mail to scheme@mc
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 30 Mar 86 13:47:32 PST
Date: Sun, 30 Mar 86 16:48:49 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: mail to scheme@mc
To: SCHEME@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].866311.860330.JAR>
If you send a message to Scheme@MC, and it gets bounced back to you due
to what might be a problem with the mailing list (invalid destinations,
etc.), please let me know (via Scheme-Request@MC) and I'll try to fix
the problem so that the next person to send a message doesn't have his
(hers) returned also. Thanks.
Jonathan
∂30-Mar-86 1927 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU [dfried%indiana.csnet: boolean?]
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 30 Mar 86 19:27:02 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 30 MAR 86 22:28:46 EST
Date: 30 Mar 1986 22:28 EST (Sun)
Message-ID: <JINX.12194976833.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: [dfried%indiana.csnet: boolean?]
In-reply-to: Msg of 30 Mar 1986 16:12-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
boolean? sounds fine to me.
∂30-Mar-86 2059 @MC.LCS.MIT.EDU:ANDY@SU-SUSHI.ARPA immutable structures
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 30 Mar 86 20:59:45 PST
Received: from SU-SUSHI.ARPA by MC.LCS.MIT.EDU 30 Mar 86 23:58:40 EST
Date: Sun 30 Mar 86 20:57:41-PST
From: Andy Freeman <ANDY@SU-SUSHI.ARPA>
Subject: immutable structures
To: scheme@MC.LCS.MIT.EDU
Message-ID: <12194993072.20.ANDY@SU-SUSHI.ARPA>
Immutable cons structures bother me.
Every other immutable structure in Scheme has a distinct reader
syntax. (I think numbers and symbols are the only ones although
strings are occasionally candidates. BTW - I think that would be a
mistake. Anyone have a use for immutable strings that can't be
satisfied by symbols?) Even if the necessary immutable-cons?
predicate is added to RRRS, that lack is fatal.
I'm reasonably convinced that there is a fundamental difference
between cons structures and numbers. Would someone please enlighten
me and justify immutable quoted structures without resorting to
"[some] formal system is cleaner without distinguishing them" as the
best reason? (Since Scheme procedures have state, mutable quoted
structures are merely syntactic sugar.)
-andy
-------
∂30-Mar-86 2241 @MC.LCS.MIT.EDU:Miller.pa@Xerox.COM non-list arguments
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 30 Mar 86 22:41:09 PST
Received: from Xerox.COM by MC.LCS.MIT.EDU 31 Mar 86 01:21:13 EST
Received: from Cabernet.ms by ArpaGateway.ms ; 30 MAR 86 22:19:17 PST
Date: 30 Mar 86 22:19 PST
From: Miller.pa@Xerox.COM
Subject: non-list arguments
To: scheme@MC.LCS.MIT.EDU,t-discussion@YALE.ARPA
cc: Miller.pa@Xerox.COM,Kahn.pa@Xerox.COM
Message-ID: <860330-221917-4500@Xerox>
(apply (lambda (x . y) (+ x y)) (cons 1 2))
Does this nescesarily work in Scheme? How about T? Common-Lisp?
(Example due to Ken Kahn)
∂30-Mar-86 2256 @MC.LCS.MIT.EDU:FAHLMAN@C.CS.CMU.EDU non-list arguments
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 30 Mar 86 22:56:33 PST
Received: from C.CS.CMU.EDU by MC.LCS.MIT.EDU 31 Mar 86 01:52:41 EST
Received: ID <FAHLMAN@C.CS.CMU.EDU>; Mon 31 Mar 86 01:51:17-EST
Date: Mon, 31 Mar 1986 01:51 EST
Message-ID: <FAHLMAN.12195013744.BABYL@C.CS.CMU.EDU>
Sender: FAHLMAN@C.CS.CMU.EDU
From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>
To: Miller.pa@XEROX.COM
Cc: Kahn.pa@XEROX.COM, scheme@MC.LCS.MIT.EDU, t-discussion@YALE.ARPA
Subject: non-list arguments
In-reply-to: Msg of 31 Mar 1986 01:19-EST from Miller.pa at Xerox.COM
It certainly doesn't work in Common Lisp because lambda lists don't do
destructuring in Common Lisp (though the argument lists for macros do
destructure).
Also, in Common Lisp you'd have to say "(function (lambda ...))".
-- Scott
∂31-Mar-86 0032 @MC.LCS.MIT.EDU:Miller.pa@Xerox.COM Re: non-list arguments
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 31 Mar 86 00:32:48 PST
Received: from Xerox.COM by MC.LCS.MIT.EDU 31 Mar 86 02:35:06 EST
Received: from Cabernet.ms by ArpaGateway.ms ; 30 MAR 86 23:33:06 PST
Date: 30 Mar 86 23:33 PST
From: Miller.pa@Xerox.COM
Subject: Re: non-list arguments
In-reply-to: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>'s message of Mon,
31 Mar 86 01:51 EST
To: Fahlman@C.CS.CMU.EDU
cc: Miller.pa@Xerox.COM, Kahn.pa@Xerox.COM, scheme@MC.LCS.MIT.EDU,
scheme%OZ@MC.LCS.MIT.EDU, t-discussion@YALE.ARPA
Message-ID: <860330-233306-4514@Xerox>
It certainly doesn't work in Common Lisp because lambda lists don't do
destructuring in Common Lisp (though the argument lists for macros do
destructure).
Also, in Common Lisp you'd have to say "(function (lambda ...))".
OK, for Common Lisp how about:
(apply #'(lambda (x &rest y) (+ x y)) (cons 1 2))
In other words, "&rest" is all the destructuring I need to ask this
question. "." is simply the cleaner way one can write it in the
Schemes.
(Sorry for the redundant scheme mailing addresses. I'm having some mail
returned and I don't know which address is causing the problem)
∂31-Mar-86 0046 @MC.LCS.MIT.EDU:FAHLMAN@C.CS.CMU.EDU non-list arguments
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 31 Mar 86 00:46:16 PST
Received: from C.CS.CMU.EDU by MC.LCS.MIT.EDU 31 Mar 86 02:50:32 EST
Received: ID <FAHLMAN@C.CS.CMU.EDU>; Mon 31 Mar 86 02:49:07-EST
Date: Mon, 31 Mar 1986 02:49 EST
Message-ID: <FAHLMAN.12195024270.BABYL@C.CS.CMU.EDU>
Sender: FAHLMAN@C.CS.CMU.EDU
From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>
To: Miller.pa@XEROX.COM
Cc: Kahn.pa@XEROX.COM, scheme%OZ@MC.LCS.MIT.EDU, scheme@MC.LCS.MIT.EDU,
t-discussion@YALE.ARPA
Subject: non-list arguments
In-reply-to: Msg of 31 Mar 1986 02:33-EST from Miller.pa at Xerox.COM
OK, for Common Lisp how about:
(apply #'(lambda (x &rest y) (+ x y)) (cons 1 2))
Ah, I see what you're driving at now.
No this is not guaranteed to work in Common Lisp in my opinion. The
second argument to apply is a list of operands. In this case, you've
got a list of one operand, 1, with a particularly ugly terminator, so
the rest arg, Y, should end up bound to NIL. Some implementations may
get this "right" by accident, but in most of them the Apply takes apart
the operand list and simulates a call to the function. The lambda would
be called with only one arg, and the rest arg would be NIL. The 2 has
been discarded before the function ever gets called.
-- Scott
∂31-Mar-86 0104 ALAN@MC.LCS.MIT.EDU non-list arguments
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 31 Mar 86 01:03:55 PST
Date: Mon, 31 Mar 86 04:05:03 EST
From: Alan Bawden <ALAN@MC.LCS.MIT.EDU>
Subject: non-list arguments
To: Miller.pa@XEROX.COM, Fahlman@C.CS.CMU.EDU
cc: SCHEME@MC.LCS.MIT.EDU, Kahn.pa@XEROX.COM,
t-discussion@YALE.ARPA
In-reply-to: Msg of 30 Mar 86 22:19 PST from Miller.pa at Xerox.COM
Message-ID: <[MC.LCS.MIT.EDU].866607.860331.ALAN>
Date: 30 Mar 86 22:19 PST
From: Miller.pa at Xerox
(apply (lambda (x . y) (+ x y)) (cons 1 2))
Date: Mon, 31 Mar 1986 01:51 EST
From: Scott E. Fahlman <Fahlman at C.CS.CMU.EDU>
It certainly doesn't work in Common Lisp because lambda lists don't do
destructuring in Common Lisp (though the argument lists for macros do
destructure).
Also, in Common Lisp you'd have to say "(function (lambda ...))".
I would translate the question into Common Lisp as:
(apply (function (lambda (x &rest y) (+ x y))) (cons 1 2))
which eliminates the question of "descructuring", but I would guess still
preserves Ken Kahn's original question. A strict reading of the Common
Lisp book would not require this to work, as far as I can see. An
implementor would seem to be within his rights to insist that the last
argument to APPLY always be a proper list.
∂31-Mar-86 0402 @MC.LCS.MIT.EDU:ramsdell%linus@mitre-bedford.ARPA Denotational semantics for SIGPLAN?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 31 Mar 86 04:02:28 PST
Received: from mitre-bedford.ARPA by MC.LCS.MIT.EDU 31 Mar 86 07:04:24 EST
Organization: The MITRE Corp., Bedford, MA
Received: by linus.MENET (4.12/4.7)
id AA12710; Mon, 31 Mar 86 07:03:58 est
Date: Mon, 31 Mar 86 07:03:58 est
From: John D. Ramsdell <ramsdell%linus@mitre-bedford.ARPA>
Posted-Date: Mon, 31 Mar 86 07:03:58 est
Message-Id: <8603311203.AA12710@linus.MENET>
To: rrrs-authors@mit-mc.ARPA
Subject: Denotational semantics for SIGPLAN?
Are there plans to include a semantic description of
Scheme in the SIGPLAN report? If the denotational
semantics is completed, I would very much like to see
Scheme presented with it.
John
P.S.
In my opinion:
1) #t and #f are preferable over #!true and #!false.
2) Its good to include the boolean? predicate.
3) Local defines should be an alternate syntax for
LETREC as advocated by Bill.
∂31-Mar-86 0733 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU non-list arguments
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 31 Mar 86 07:32:57 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 31 MAR 86 09:34:19 EST
Date: 31 Mar 1986 09:33 EST (Mon)
Message-ID: <JINX.12195097950.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Miller.pa@XEROX.COM
Cc: Kahn.pa@XEROX.COM, scheme@MC.LCS.MIT.EDU, t-discussion@YALE.ARPA
Subject: non-list arguments
In-reply-to: Msg of 31 Mar 1986 01:19-EST from Miller.pa at Xerox.COM
The Revised Revised Report on Scheme states that the second argument
(2 argument form) to APPLY must be a "proper" list. Individual
implementations are free to extend the semantics of APPLY.
APPLY in MIT Scheme signals an error when given somthing other than a
"proper" list.
∂31-Mar-86 0813 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA Scheme BNF
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 31 Mar 86 08:12:57 PST
Received: from GODOT.THINK.COM by MC.LCS.MIT.EDU 31 Mar 86 11:14:32 EST
Received: from guido by GODOT.THINK.COM via CHAOS; Mon, 31 Mar 86 11:13:06 est
Date: Mon, 31 Mar 86 11:14 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: Scheme BNF
To: JAR@MC.LCS.MIT.EDU, willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU, gls@THINK-AQUINAS.ARPA
In-Reply-To: <[MC.LCS.MIT.EDU].865763.860329.JAR>
Message-Id: <860331111447.3.GLS@GUIDO.THINK.COM>
Date: Sat, 29 Mar 86 17:41:34 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
... But in order to allow (BEGIN) to work,
we have to add an exception to the description "BEGIN evaluates the
forms sequentially, and returns the value of the last form" - you have
to say "...except that if there are no forms, the value is unspecified".
I have written interpreters and compilers that deal with (BEGIN) and
they always have an extra conditional in them to be able to deal with
that as a special case. ...
The problem is with the form of the English; it blithely assumes that
there is a last form. This is actually a fencepost error; we should
focus on the spaces between the forms, and not the forms themselves.
After the word BEGIN there is an <unspecified>, and after each subform
the value of that form appears. BEGIN forms a sequence r of the
<unspecified> value and the values of all the forms, and then returns
(reduce #'(lambda (x y) y) r). Clear?
To render this as a DO loop:
(define (interpret-begin begin-form environment)
(do ((forms (cdr begin-form) (cdr forms))
(result <unspecified> (interpret-form (car forms) environment)))
((null forms) result)))
See? No special cases.
--Guy
∂31-Mar-86 0829 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA meaning of local define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 31 Mar 86 08:29:41 PST
Received: from GODOT.THINK.COM by MC.LCS.MIT.EDU 31 Mar 86 11:18:39 EST
Received: from guido by GODOT.THINK.COM via CHAOS; Mon, 31 Mar 86 10:32:46 est
Date: Mon, 31 Mar 86 10:34 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: meaning of local define
To: LS.JINX@DEEP-THOUGHT.MIT.EDU, JAR@MC.LCS.MIT.EDU
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU, gls@THINK-AQUINAS.ARPA
In-Reply-To: <LS.JINX.12194385065.BABYL@MIT-EECS>
Message-Id: <860331103424.1.GLS@GUIDO.THINK.COM>
Am I confused! I don't understand why good style allows global DEFINE
to be used to define things other than procedures, but not local DEFINE.
It seems to me that in general one ought to be able to use the same
construct in the same way no matter where it appears. Call this
principle "stylistic transparency". Am I confused?
As another example of this, one of the things currently distressing some
users of Common Lisp is that
(let ((seed (get-universal-time)))
(defun random (n)
(setq seed (random-mungicate seed))
(random-result seed n)))
doesn't compile properly in all Common Lisp implementations because of
ad hoc restrictions on where DEFUN is recognized.
--Guy
∂31-Mar-86 1024 @MC.LCS.MIT.EDU:ANDY@SU-SUSHI.ARPA immutable structures
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 31 Mar 86 10:24:28 PST
Received: from SU-SUSHI.ARPA by MC.LCS.MIT.EDU 31 Mar 86 13:09:58 EST
Date: Mon 31 Mar 86 10:07:51-PST
From: Andy Freeman <ANDY@SU-SUSHI.ARPA>
Subject: immutable structures
To: rrrs-authors@MC.LCS.MIT.EDU
Message-ID: <12195136917.17.ANDY@SU-SUSHI.ARPA>
Immutable cons structures bother me.
Every other immutable structure in Scheme has a distinct reader
syntax. (I think numbers and symbols are the only ones although
strings are occasionally candidates. BTW - I think that would be a
mistake. Anyone have a use for immutable strings that can't be
satisfied by symbols?) Even if the necessary immutable-cons?
predicate is added to RRRS, that lack is fatal.
I'm reasonably convinced that there is a fundamental difference
between cons structures and numbers. Would someone please enlighten
me and justify immutable quoted structures without resorting to
"[some] formal system is cleaner without distinguishing them" as the
best reason? (Since Scheme procedures have state, mutable quoted
structures are merely syntactic sugar.)
-andy
-------
∂31-Mar-86 1051 JAR@MC.LCS.MIT.EDU meaning of local define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 31 Mar 86 10:51:34 PST
Date: Mon, 31 Mar 86 13:53:30 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: meaning of local define
To: gls@AQUINAS.THINK.COM
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU, LS.JINX@DEEP-THOUGHT.MIT.EDU
In-reply-to: Msg of Mon 31 Mar 86 10:34 EST from Guy Steele <gls at THINK-AQUINAS.ARPA>
Message-ID: <[MC.LCS.MIT.EDU].867067.860331.JAR>
Date: Mon, 31 Mar 86 10:34 EST
From: Guy Steele <gls at THINK-AQUINAS.ARPA>
Am I confused! I don't understand why good style allows global DEFINE
to be used to define things other than procedures, but not local DEFINE.
It seems to me that in general one ought to be able to use the same
construct in the same way no matter where it appears. Call this
principle "stylistic transparency". Am I confused?
I agree with this... I guess this is why I thought it might be better to
allow define's to be interspersed with other expressions in
lambda-bodies, and saying they're evaluated sequentially, for uniformity
with "top level".
As another example of this, one of the things currently distressing some
users of Common Lisp is that
(let ((seed (get-universal-time)))
(defun random (n)
(setq seed (random-mungicate seed))
(random-result seed n)))
doesn't compile properly in all Common Lisp implementations because of
ad hoc restrictions on where DEFUN is recognized.
In spite of the wishes of many, we're not able at this point to change
define's from being local to being global (like in T, Common Lisp, and
some others dialects, I think), which would be one way to get rid of ad
hoc restrictions. Another fix would be to allow local define's to
appear anywhere, like in some versions of MIT Scheme, but this is hard
to implement well and at least as confusing as restricting the contexts
in which they're available. So I think we're stuck with the context
restrictions.
It's implicit in the RRRS that definitions aren't expressions, and I'm
changing the prose for the R↑3RS (?) to make this even clearer; see also
the BNF I sent out. I admit this is more complex, and arguably ad hoc,
but I am hoping that changing the report to emphasize that define's
aren't expressions will help make them seem not ad hoc; the restrictions
will be up front.
Jonathan
∂31-Mar-86 1055 JAR@MC.LCS.MIT.EDU (BEGIN)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 31 Mar 86 10:55:01 PST
Date: Mon, 31 Mar 86 13:57:02 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: (BEGIN)
To: gls@AQUINAS.THINK.COM
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Mon 31 Mar 86 11:14 EST from Guy Steele <gls at THINK-AQUINAS.ARPA>
Message-ID: <[MC.LCS.MIT.EDU].867079.860331.JAR>
Date: Mon, 31 Mar 86 11:14 EST
From: Guy Steele <gls at THINK-AQUINAS.ARPA>
...
See? No special cases.
OK, I don't feel strongly, and I haven't heard anyone but me speak up
against allowing (BEGIN) and (LAMBDA (X)) and things like that. So I
guess that unless the debate heats up again I'll change the report.
∂31-Mar-86 1058 JAR@MC.LCS.MIT.EDU Denotational semantics for SIGPLAN?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 31 Mar 86 10:57:47 PST
Date: Mon, 31 Mar 86 13:59:45 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: Denotational semantics for SIGPLAN?
To: ramsdell%linus@MITRE-BEDFORD.ARPA
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Mon 31 Mar 86 07:03:58 est from John D. Ramsdell <ramsdell%linus at mitre-bedford.ARPA>
Message-ID: <[MC.LCS.MIT.EDU].867082.860331.JAR>
Date: Mon, 31 Mar 86 07:03:58 est
From: John D. Ramsdell <ramsdell%linus at mitre-bedford.ARPA>
Are there plans to include a semantic description of
Scheme in the SIGPLAN report? If the denotational
semantics is completed, I would very much like to see
Scheme presented with it.
Yes, it's in the works.
∂31-Mar-86 1352 JAR@MC.LCS.MIT.EDU non-list arguments
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 31 Mar 86 13:51:24 PST
Date: Mon, 31 Mar 86 16:52:27 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: non-list arguments
To: Fahlman@C.CS.CMU.EDU
cc: SCHEME@MC.LCS.MIT.EDU, Kahn.pa@XEROX.COM, Miller.pa@XEROX.COM,
t-discussion@YALE.ARPA
In-reply-to: Msg of Mon 31 Mar 1986 01:51 EST from Scott E. Fahlman <Fahlman at C.CS.CMU.EDU>
Message-ID: <[MC.LCS.MIT.EDU].867344.860331.JAR>
Date: Mon, 31 Mar 1986 01:51 EST
From: Scott E. Fahlman <Fahlman at C.CS.CMU.EDU>
It certainly doesn't work in Common Lisp because lambda lists don't do
destructuring in Common Lisp (though the argument lists for macros do
destructure).
Scheme and T don't have lambda list destructuring; they just use "."
instead of "&rest".
I haven't checked the manuals for T or Scheme but it was certainly the
intent that the list passed to APPLY is unrelated to the list that a
rest-parameter gets bound to. The rest-list should always be freshly
consed, so e.g. the procedure LIST is equivalent to (LAMBDA X X). The
last argument to APPLY must be a proper list. I think Common Lisp takes
the same stance.
∂31-Mar-86 1541 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU (BEGIN)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 31 Mar 86 15:41:37 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 31 MAR 86 18:43:20 EST
Date: 31 Mar 1986 18:42 EST (Mon)
Message-ID: <JINX.12195197909.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: gls@AQUINAS.THINK.COM, RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: (BEGIN)
In-reply-to: Msg of 31 Mar 1986 13:57-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
I agree with you. I don't think (BEGIN) or (LAMBDA (X)) should be
allowed.
∂31-Mar-86 1701 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU meaning of local define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 31 Mar 86 17:00:55 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 31 MAR 86 19:46:26 EST
Date: 31 Mar 1986 19:45 EST (Mon)
Message-ID: <JINX.12195209368.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: gls@AQUINAS.THINK.COM, LS.JINX%DEEP-THOUGHT.MIT.EDU@XX.LCS.MIT.EDU,
RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: meaning of local define
In-reply-to: Msg of 31 Mar 1986 13:53-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
Am I confused! I don't understand why good style allows global DEFINE
to be used to define things other than procedures, but not local DEFINE.
It seems to me that in general one ought to be able to use the same
construct in the same way no matter where it appears. Call this
principle "stylistic transparency". Am I confused?
I agree with this... I guess this is why I thought it might be better to
allow define's to be interspersed with other expressions in
lambda-bodies, and saying they're evaluated sequentially, for uniformity
with "top level".
The problem is this:
In the following (horrible) code
(define (quux x) (* x x))
(define (foo y)
(define bar (quux y))
(define (quux x) (* x x x))
(quux y))
We have various options:
1) The first reference to QUUX gives the value of the outer QUUX and
the second gives the value of the inner QUUX since the inner one has
not been defined yet. This is what the interpreter in chapter 4 of
S&ICP does. This seems very ugly since it implies one of 2 things:
- Definitions modify environments to have new bindings. The definition
causes a side effect to the environment where it occurs. This is
pretty ugly.
- Definitions create new environments where the rest of the
expressions are evaluated. This has clear problems with mutual
recursion.
2) Both references result in the inner QUUX since the DEFINEs are
equivalent to a LETREC, and there exists an order in which the
definitions can be evaluated which gives this result. This would be
easy to arrange if Scheme were evaluated in normal order, but hard
(in general) given that it is applicative order.
3) It is an error because the definitions occur all in parallel but
the values are assigned sequentially, and thus QUUX is bound but not
assigned on first use. This is what MIT Scheme does currently (and
used to do for top level).
I would like 2 to hold, but it unfortunately does not. Making 3 the
official semantics would be like specifying an order of argument
evaluation which people would then take advantage of. Restricting the
values to be lambda expressions guarantees that the result does not
depend on the order of evaluation, while attempting to extend this
(constants, expressions which depend only on outer variables, etc.)
gets us into a sort of operational semantics.
The sort of thing CPH and I are trying to avoid is the same thing that
I (we ?) abhor about the definition of REC and LETREC, namely that
(rec a (cons 3 a))
does not work, while
(rec a (cons 3 (lambda () a)))
does.
We are making the implementation visible in the language definition.
BTW, I restrict my use of top level DEFINE so that it does not depend
in the potential sequentiality of evaluation.
∂31-Mar-86 1722 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU LETREC (REC)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 31 Mar 86 17:21:50 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 31 MAR 86 20:00:53 EST
Date: 31 Mar 1986 19:59 EST (Mon)
Message-ID: <JINX.12195211902.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: LETREC (REC)
In-reply-to: Msg of 31 Mar 1986 19:45-EST from Bill Rozas <JINX at OZ.AI.MIT.EDU>
As you probably know by now, there is a feature that I REALLY dislike
about LETREC (REC), namely that LETREC allows non-lambda expressions
in the binding list. I would like to make this optional and make the
standard allow only lambda expressions. Is there a lot of opposition
to this? I realize that it may be too late for this, and should
probably have objected very strongly at last year's meeting, but I've
thought a lot about the issue since then and I am becoming
progressively more upset with the way it is now.
∂31-Mar-86 2309 @MC.LCS.MIT.EDU:KMP@SCRC-STONY-BROOK.ARPA Scheme BNF
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 31 Mar 86 23:08:53 PST
Received: from SCRC-STONY-BROOK.ARPA by MC.LCS.MIT.EDU 1 Apr 86 02:10:50 EST
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 451605; Tue 1-Apr-86 02:05:34-EST
Date: Tue, 1 Apr 86 02:08 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: Scheme BNF
To: gls%aquinas@THINK.ARPA, JAR@MC.LCS.MIT.EDU,
willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-Reply-To: <860331111447.3.GLS@GUIDO.THINK.COM>
Message-ID: <860401020800.6.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Date: Mon, 31 Mar 86 11:14 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Date: Sat, 29 Mar 86 17:41:34 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
... But in order to allow (BEGIN) to work,
we have to add an exception to the description "BEGIN evaluates the
forms sequentially, and returns the value of the last form" - you have
to say "...except that if there are no forms, the value is unspecified".
I have written interpreters and compilers that deal with (BEGIN) and
they always have an extra conditional in them to be able to deal with
that as a special case. ...
The problem is with the form of the English; it blithely assumes that
there is a last form. This is actually a fencepost error; we should
focus on the spaces between the forms, and not the forms themselves.
After the word BEGIN there is an <unspecified>, and after each subform
the value of that form appears. BEGIN forms a sequence r of the
<unspecified> value and the values of all the forms, and then returns
(reduce #'(lambda (x y) y) r). Clear?
I second GLS's motion to make (BEGIN) and (LAMBDA ()) legal. The problem is
no worse than explaining why (AND) and (OR) are valid.
This same issue has come up in a number of Lisp dialects I've worked with.
I've never had a need for (BEGIN), (LAMBDA ()), etc. in a situation where
I cared about the value, so I'd be quite happy to leave the value undefined
as long as side-effects happen correctly. The situation where it comes up
a lot is in program-writing programs. I end up writing:
`(LAMBDA () ,@(IF (NOT THE-FORMS) '(NIL) THE-FORMS))
when I wish I could write:
`(LAMBDA () ,@THE-FORMS)
∂01-Apr-86 0007 @MC.LCS.MIT.EDU:KMP@SCRC-STONY-BROOK.ARPA New special forms -- CALL and VAR (or some such)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 1 Apr 86 00:07:29 PST
Received: from SCRC-STONY-BROOK.ARPA by MC.LCS.MIT.EDU 1 Apr 86 02:25:20 EST
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 451612; Tue 1-Apr-86 02:19:54-EST
Date: Tue, 1 Apr 86 02:22 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: New special forms -- CALL and VAR (or some such)
To: RRRS-AUTHORS@MIT-MC.ARPA
Message-ID: <860401022221.7.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
I find the presentation of special forms very clumsy. I believe that it would be
much smoother if we would introduce two new special forms. I call them VAR and CALL.
Jonathan points out that the VAR special form was effectively in the original
(unrevised) SCHEME report as the STATIC special form. In any case, the idea would
be that (VAR X) is the same as X in a program. (CALL X . args) would be the same as
(X . args) where X didn't name a special form. I'm susceptible to other names. eg,
VARIABLE-REFERENCE is a fine alternative for VAR. FUNCTION-CALL, COMPOSITION, or
FUNCTION-COMPOSITION are ok for CALL. The main point is that it should be possible
to define the language completely in terms of special forms. eg, we first introduce
expressions that look like:
(LAMBDA (X Y) (CALL (VAR +) (VAR X) (VAR Y)))
and then introduce abbreviations for VAR and CALL forms such that
(LAMBDA (X Y) (+ X Y))
means the same thing. The result is that when describing evaluable expressions
you don't have to disjoin into (keyword . ...) and (fn . ...). Instead, you get a
fair amount of mileage in the initial exposition out of just saying that there are
only special forms, and then relaxing the description.
Early T had these primitives, and I thought they made my first T manual look nicer,
but they seem to have gotten lost over time.
Anyway, does anybody buy this idea?
--- Text that follows is just for fun and not part of the above proposal ---
By the way, in the early T it was even possible to write:
(LAMBDA (0 1) (CALL (VAR +) (VAR 0) (VAR 1)))
or
(LAMBDA (0 1) (+ (VAR 0) (VAR 1)))
ie, you could have non-symbol variable names. This got lost at some point, but I
still think this was kinda fun.
As a hack, I even wrote things like:
(DEFINE (GENSYM)
(LET ((CELL (LIST 'VAR NIL)))
(SET (CADR CELL) CELL)
CELL))
(DEFINE FOO (LET ((V1 (GENSYM))
(V2 (GENSYM)))
(ENCLOSE `(LAMBDA (,V1 ,V2) (+ ,V1 ,V2)))))
(FOO 1 2) => 3
The reason for the CADR-circular result of GENSYM may not be completely obvious
on first glance. I think it's the only way to satisfy the relevant constraints,
though. I certainly won't try to argue that this was the "right thing", but it
certainly struck me as novel. Hope some of you find it amusing...
∂01-Apr-86 0523 @MC.LCS.MIT.EDU:KWH@AI.AI.MIT.EDU LETREC (REC)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 1 Apr 86 05:17:53 PST
Received: from AI.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 1 APR 86 08:19:50 EST
Date: Tue, 1 Apr 86 08:19:07 EST
From: Ken Haase <KWH@AI.AI.MIT.EDU>
Subject: LETREC (REC)
To: JINX@OZ.AI.MIT.EDU
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of 31 Mar 1986 19:59 EST (Mon) from Bill Rozas <JINX%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
Message-ID: <[AI.AI.MIT.EDU].22994.860401.KWH>
I'd like to defend the use of non-lambda expressions in LETREC; lambda
is only one of the function specifying forms a user may wish to invoke.
If a programmer uses a lot of higher order functions in specifying her
programs, it seems completely reasonable for her to be able to use these
forms for recursive definitions. Certainly when binding non-procedures,
the use of LETREC is ugly and ill-defined; but when binding procedures it
seems perfectly consistent and nice to have. Consider the following code:
(define (when test result)
(lambda (x) (if (test x) x (result x))))
(define (iterate n action)
(letrec ((foo (until zero? (lambda (x) (print x) (foo x)))))
(foo n)))
Here foo is being bound to a non-lambda expression one of whose arguments
is a lambda-expression which calls foo. I think this is perfectly reasonable,
as long as the recursive reference only occurs within defining forms like lambda;
and if it doesn't there's already an error to handle the case (unbound identifier).
Ken
∂01-Apr-86 0650 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU LETREC (REC)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 1 Apr 86 06:50:10 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 1 APR 86 09:48:09 EST
Date: 1 Apr 1986 09:47 EST (Tue)
Message-ID: <JINX.12195362618.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Ken Haase <KWH@AI.AI.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: LETREC (REC)
In-reply-to: Msg of 1 Apr 1986 08:19-EST from Ken Haase <KWH at AI.AI.MIT.EDU>
Certainly when binding non-procedures,
the use of LETREC is ugly and ill-defined
Unfortunately it is not ill defined. A simple "operational"
description (like the one in the currentl version of RRRS) describes
what is legal and what is not. I view this operational description as
a crock, and the only way that I can see to restrict the use of LETREC
to reasonable cases is to "over-restrict" it.
The problem is that it is hard to decide when to stop. The boundary
is fuzzy, but I'd be much happier with the restriction than with the
current semantics.
Here foo is being bound to a non-lambda expression one of whose arguments
is a lambda-expression which calls foo. I think this is perfectly reasonable,
as long as the recursive reference only occurs within defining forms like lambda;
and if it doesn't there's already an error to handle the case (unbound identifier).
If we start along these lines, what happens to macros that expand into
lambdas? What if we use the definition of begin in RABBIT?
Constraining it to "defining" forms is not enough, the lambda
expressions must not be invoked until after all the expressions have
been evaluated, but this is too complicated.
Note that the error is not unbound variable. The variable is bound,
since the expressions are evaluated in an environment where the names
are bound. At best it is unassigned, but this implies that there are
side effects going on, which I don't like.
∂01-Apr-86 0653 NET-ORIGIN@MC.LCS.MIT.EDU #t and #f
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 1 Apr 86 06:53:39 PST
Received: from ZERMATT.LCS.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 1 APR 86 09:49:38 EST
Received: from ASPEN.LCS.MIT.EDU by MIT-ZERMATT.ARPA via CHAOS with CHAOS-MAIL id 29836; Tue 1-Apr-86 09:49:25-EST
Date: Tue, 1 Apr 86 09:48 EST
From: Robert Halstead <rhh@MIT-VAX.ARPA>
Subject: #t and #f
To: JAR@MIT-MC.ARPA
cc: RRRS-AUTHORS@MIT-MC.ARPA
In-Reply-To: <[MC.LCS.MIT.EDU].865699.860329.JAR>
Message-ID: <860401094840.2.RHH@ASPEN.LCS.MIT.EDU>
I like #t and #f, and I'm even at MIT! -b.
∂01-Apr-86 0722 @MC.LCS.MIT.EDU:kelsey@YALE.ARPA #t, #f, and (BEGIN)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 1 Apr 86 07:18:51 PST
Received: from yale-bulldog by MC.LCS.MIT.EDU 1 Apr 86 10:20:45 EST
Received: by Yale-Bulldog.YALE.ARPA; 1 Apr 86 10:07:04 EST (Tue)
Date: 1 Apr 86 10:07:04 EST (Tue)
From: Richard Kelsey <kelsey@YALE.ARPA>
Message-Id: <8604011507.AA03682@Yale-Bulldog.YALE.ARPA>
Subject: #t, #f, and (BEGIN)
To: JAR@MIT-MC.ARPA
Cc: RRRS-AUTHORS@MIT-MC.ARPA
Two votes:
I much prefer #t and #f over #!true and #!false.
I also think that (BEGIN) and (LAMBDA (X)) should not be allowed.
-Richard Kelsey
-------
∂01-Apr-86 0904 NET-ORIGIN@MC.LCS.MIT.EDU meaning of local define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 1 Apr 86 09:04:11 PST
Received: from ZERMATT.LCS.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 1 APR 86 12:04:29 EST
Received: from ASPEN.LCS.MIT.EDU by MIT-ZERMATT.ARPA via CHAOS with CHAOS-MAIL id 29860; Tue 1-Apr-86 12:04:18-EST
Date: Tue, 1 Apr 86 12:03 EST
From: Robert Halstead <rhh@MIT-VAX.ARPA>
Subject: meaning of local define
To: JINX@OZ.AI.MIT.EDU
cc: JAR@MIT-MC.ARPA, RRRS-AUTHORS@MIT-MC.ARPA
In-Reply-To: <JINX.12195209368.BABYL@MIT-OZ>
Message-ID: <860401120334.3.RHH@ASPEN.LCS.MIT.EDU>
...
(define (quux x) (* x x))
(define (foo y)
(define bar (quux y))
(define (quux x) (* x x x))
(quux y))
...
3) It is an error because the definitions occur all in parallel but
the values are assigned sequentially, and thus QUUX is bound but not
assigned on first use. This is what MIT Scheme does currently (and
used to do for top level).
Multilisp has adopted a position which is a superset of this. I'm not
terribly strongly attached to it, but I think it is pragmatic given that
none of the alternatives is wonderfully appealing. DEFINEs are allowed
to appear anywhere at the "top level" (which includes possibly being
nested inside BEGINs) of a "variable-binding form" (which means lambda
bodies, let bodies, and the like). They may be interspersed with other
non-DEFINE forms -- in other words, they don't have to all be collected
at the beginning of a body. The meaning of DEFINEs is specified by the
following (operationally stated) rule: all variables named in DEFINEs
at the top level of a particular body are bound to unassigned values on
entry to that body, and the DEFINEs themselves are changed to SET!s and
left where they are in the body. This implies a little more work for a
compiler or interpreter than the current RRRS position, but I don't
think it's really much uglier since even the current RRRS stance allows
arbitrary computations to occur in calculating the values to be bound to
some DEFINEd variables without waiting for all the variables' values to
have been assigned.
I think we should decide if we want DEFINE merely for compatibility with
S&ICP (in which case we should scan the book & find out the minimal
semantically appealing definition that will work for all the examples
given) or whether we would put DEFINE in the Scheme standard even if
S&ICP didn't mention it (in which case a debate about more "powerful"
versions is appropriate). I tend toward a theory that essential Scheme
should only include the minimum required for S&ICP to work. But I'll
confess I still find it a muddle to know how to proceed from that
decision.
∂01-Apr-86 0911 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU MIT Scheme, general information (long message)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 1 Apr 86 09:10:13 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 1 APR 86 12:10:22 EST
Date: 1 Apr 1986 12:09 EST (Tue)
Message-ID: <JINX.12195388412.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: scheme@MC.LCS.MIT.EDU
cc: info-cscheme%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU,
puzo%PREP.AI.MIT.EDU@XX.LCS.MIT.EDU
Subject: MIT Scheme, general information (long message)
There are currently 2 implementations of MIT Scheme:
"Gator" Scheme runs on HP 9000 series 200 (and old model 9836 plus
variants) computers under the Pascal 3.1 operating system. It is
quite dependent on this operating system and the tools provided with
it. This is currently our main implementation. Most of the code is
written in Scheme, but the interpreter and support procedures
(operating system interface) are written in assembly language
(Motorola 68000) and Pascal (HP dialect). There is a very
idiosincratic compiler (Liar) in this version which with motherly care
or luck can give very good performance, but which will not perform so
well without pampering. There is also a very good editor (Edwin)
written in Scheme. It is very similar to GNU Emacs, but its interface
to Scheme is (for obvious reasons) better.
CScheme (pronounced like "see-scheme") runs on a variety of machines
which have C compilers. In particular, it runs on Vaxen (both BSD4.2
Unix and VMS), various flavors of Unix (HP-UX, Sun BSD), and is quite
portable, but may require some work on "strange" machines and/or
operating systems. This version (the interpreter and support
routines, which are written in C) was originally written to illustrate
how a Scheme system could be built, not as a "production" version.
Its main emphasis was clarity, rather than efficiency. As of late,
with (slowly) increasing efficiency and use, it is becoming the base
for a variety of projects. Its performance is adequate (although not
great) on the latest generation single user workstations (Suns, HP
9000 series 300, etc). There is currently no compiler for this
version. There is a moderately good (although not perfect) interface
to GNU Emacs, and a barely adequate interface to DEC Emacs for VMS.
Both systems are pretty similar as far as "normal" users are concerned
(the systems share the code written in Scheme although they are
currently somewhat out of phase). Both versions also require large
amounts of memory (upwards of 4 Mb for Gator Scheme with all the
features, somewhat over 2 Mb for Cscheme).
Within the next few months (by September '86 probably) we will shift
from Gator Scheme to CScheme (CScheme will become our main
implementation), and there will be a (new) compiler for CScheme with
back ends at least for the common machines (68k family and Vax).
Eventually we plan to have a C back end also (does anybody know of a
portable dynamic loader for C/Unix ?). Edwin will also be ported to
CScheme (at least under versions of Unix providing the curses(3)
library).
For more information about either version, send (arpa) mail to
SCHEME-TEAM%MIT-OZ@MIT-MC
or US Snail to
Scheme Team
c/o Prof. Hal Abelson
545 Technology Sq. rm 410
Cambridge MA 02139
For particular information about CScheme, send mail to
INFO-CSCHEME%MIT-OZ@MIT-MC (send mail to info-cscheme-request to be
added to this mailing list)
To obtain a copy of MIT Scheme
1) If you want CScheme, and have access to the arpanet, a "tar" file
(for Unix) exists on MIT-PREP /scheme/dist.tar . There is usually a
"compressed" (dist.tar.Z) file also. If the file does not exist for
any reason, log in (via telnet) to MIT-PREP as scheme (no password).
The files will be re-generated by the log in program.
2) If you can use ftp over the arpanet, but cannot use a tar file, get
in touch with us describing what version you want, and we may be able
to arrange some way to get the sources across the net.
3) Otherwise, try to get a copy from someone who already has it.
4) As a last resort (unadvisable), send $200 to the address above, and
specify what form of tape you want. We can currently provide
1600 bpi standard tar tape.
1600 bpi standard VMS backup tape.
HP-UX cartridge tar tape.
∂01-Apr-86 1043 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: small changes
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 1 Apr 86 10:43:17 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 1 Apr 86 13:44:43 EST
Received: from indiana by csnet-relay.csnet id a021966; 1 Apr 86 13:26 EST
Date: Tue, 1 Apr 86 09:59:12 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: JAR@mc.lcs.mit.edu
Subject: Re: small changes
Cc: RRRS-AUTHORS@mc.lcs.mit.edu
If you insist on going counter to the Brandeis decision, making your
implementation and book case-sensitive, ...
My system (Chez Scheme) and book (on Scheme programming, with Bruce
Smith of UNC) will not go counter to any Brandeis decision, unless,
of course, the change is incorporated into the RRRS.
Why would I bother spending all this time dealing with this stuff if
I planned to ignore the RRRS anyway? I may be stubborn but I'm not
stupid.
∂01-Apr-86 1110 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Case Sensitivity
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 1 Apr 86 11:10:39 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 1 Apr 86 13:45:25 EST
Received: from indiana by csnet-relay.csnet id ac21966; 1 Apr 86 13:27 EST
Date: Tue, 1 Apr 86 10:33:41 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: RRRS-AUTHORS@mc.lcs.mit.edu
Subject: Case Sensitivity
I am most concerned about the system taking a mixed-case program
and printing it all in one case (e.g., during debugging, editing
or pretty-printing). I would be willing (with reluctance) to
allow systems to treat HitMe and HITME as the same identifier.
It is not impossible to have a system that retains symbols as
the user types them yet treats two symbols differing only in
case as the same identifier, it is just difficult and probably
not worth the effort.
Unless I have convinced everyone to be case-sensitive, I would
like the RRRS not to specify one way or another. I prefer the
first of Jonathan's solutions:
1. It's OK to write it, but only programs (and data files) which don't
care one way or the other (using lower case for the things in the
manual, and don't depend on EITHER (eq? 'foo 'Foo) or (not (eq? 'foo
'Foo))), will be portable.
∂01-Apr-86 1239 GJC@MC.LCS.MIT.EDU MIT Scheme, linking C compiler output.
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 1 Apr 86 12:37:47 PST
Date: Tue, 1 Apr 86 15:38:33 EST
From: "George J. Carrette" <GJC@MC.LCS.MIT.EDU>
Subject: MIT Scheme, linking C compiler output.
To: JINX@OZ.AI.MIT.EDU
cc: SCHEME@MC.LCS.MIT.EDU, puzo@PREP.AI.MIT.EDU
In-reply-to: Msg of 1 Apr 1986 12:09 EST (Tue) from Bill Rozas <JINX%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
Message-ID: <[MC.LCS.MIT.EDU].868688.860401.GJC>
Franz lisp uses the unix assembler, and so has a dynamic
linker for foo.o files. Yale "T" also used .o files
for bootstrap in the past. The format is usually grossly simple,
although the SYSTEM-V format is more general and complicated.
I have to do a dynamic linker for LMI's system-V unix in order
to have, well, the flexibility of dynamic linking. It will
be written in either C or lisp.
∂01-Apr-86 1302 NET-ORIGIN@MC.LCS.MIT.EDU non-list arguments
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 1 Apr 86 13:01:34 PST
Received: from ZERMATT.LCS.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 1 APR 86 15:27:48 EST
Received: from ASPEN.LCS.MIT.EDU by MIT-ZERMATT.ARPA via CHAOS with CHAOS-MAIL id 29890; Tue 1-Apr-86 15:27:29-EST
Date: Tue, 1 Apr 86 15:26 EST
From: Robert Halstead <rhh@MIT-VAX.ARPA>
Subject: non-list arguments
To: JAR@MIT-MC.ARPA
cc: SCHEME@MIT-MC.ARPA, t-discussion@YALE.ARPA
In-Reply-To: <[MC.LCS.MIT.EDU].867344.860331.JAR>
Message-ID: <860401152644.7.RHH@ASPEN.LCS.MIT.EDU>
I haven't checked the manuals for T or Scheme but it was certainly the
intent that the list passed to APPLY is unrelated to the list that a
rest-parameter gets bound to. The rest-list should always be freshly
consed, so e.g. the procedure LIST is equivalent to (LAMBDA X X). The
last argument to APPLY must be a proper list. I think Common Lisp takes
the same stance.
A quick scan of the Common Lisp book leaves the question unresolved;
maybe Guy Steele could comment. However, I have seen object-oriented
programs where this would probably lead to less than the most efficient
implementation. Suppose we represent objects by procedures and call
them using the general form
(<object> <key> <other stuff>)
where the <key> indicates the operation to be performed on <object> and
<other stuff> (possibly empty) consists of operation-dependent
parameters. One way to code up such an object is as
(lambda (key . rest)
(cond ((eq? key 'foo) (apply f1 rest))
((eq? key 'bar) (apply f2 (cons 'barbar rest)))
...))
where we use the key to pick a function (or new object) to forward the
request to, on the assumption that somebody at the end of the chain will
actually use the rest of the original arguments. Putting an extra list
copy in at each forwarding step seems mildly expensive and somewhat
unnecessary. I don't think that LAMBDA should be prohibited from
checking that its argument is a true list, or from copying it over, but
I also don't think it should be required to. Why is it important for
the list of rest arguments to be copied over when we don't, for example,
expect quoted lists to be copied over every time an expression '(...) is
evaluated?
To summarize, I think it should be permissible for
(eq? ((lambda x x) l) l)
to return true, but it should not be a requirement. Furthermore, it
should be permissible for an implementation to report an error if l in
the above expression is not a true list, but an implementation should
not be required to do so. Of course, it would still be true that
((lambda x x) 3 4 5)
would return a freshly consed list, just like (list 3 4 5). An
interesting question: do people expect (apply list l) to return a
top-level copy of l? -b.
∂01-Apr-86 1840 JAR@MC.LCS.MIT.EDU changes
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 1 Apr 86 18:40:43 PST
Date: Tue, 1 Apr 86 21:42:41 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: changes
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].869021.860401.JAR>
I intend to add all the hyperbolic trig functions to Scheme. Also, the
gamma function, Bessel functions, and Legendre polynomials. I use these
all the time and don't know how anyone gets by without them.
I think Scheme numbers are really ad hoc. The ring should be a required
argument to +, *, etc. so that they know where the answer should come
from. (E.g. (+ 4 7 (MOD Z 5)) ==> 1.) Scheme should support arithmetic
mod N, polynomial arithmetic, and arithmetic in arbitrary algebraic
number fields. Complex number fall out as a special case:
(SQRT -1 (MOD (POLY R) (LAMBDA (X) (+ (* X X) 1 R)))) ==> 1i
This should be easy to implement.
I don't see why we need all these random special forms. For example,
there's no need to have QUOTE or LAMBDA. We can write
(SET! (X Y Z) (+ X (* Y Z N) N))
instead of
(LAMBDA (X Y Z) (+ X (* Y Z N) N)).
No ambiguity will result because if the first thing is a list then
obviously the expression can't be an assignment. Similarly, we should
be writing
(SET! (D #(A (B C) 4)))
instead of
(QUOTE (D #(A (B C) 4)))
because what would one-argument SET! mean?
I don't understand why there's no existential quantifer in Scheme.
For example, I often find myself wanting to write
(EXISTS (X) (AND (MEMQ X L1) (MEMQ X L2)))
to find out whether the lists L1 and L2 intersect.
If we have first-class continuations I don't see any reason why we
shouldn't have first-class stores also. E.g.
(LET ((Z (CONS 1 2)))
(CALL-WITH-CURRENT-STORE
(LAMBDA (S)
(SET-CAR! Z 3)
(LIST (CAR Z) (S (LAMBDA () (CAR Z)))))))
==> (3 1)
And while we're on the subject of modules, why don't we just adopt
Common Lisp's package system wholesale? It's really useful and elegant.
Also Zetalisp's LOOP construct is really good.
I'll put all these features in the report (Penguin Books has already
expressed interest, by the way) unless people send me enough money.
Modestly,
Jonathan Rees
Editor
∂01-Apr-86 2058 JAR@MC.LCS.MIT.EDU begin
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 1 Apr 86 20:49:11 PST
Date: Tue, 1 Apr 86 23:51:08 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: begin
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].869376.860401.JAR>
One more thing... I want to change the syntax of BEGIN as follows:
<expr> ::= (begin <block> <optional end>)
<block> ::= <definition>* <expr>+
<optional end> ::= end | <empty>
This is for compatibility with Algol 60, which allows declarations at the
beginning of begin...end blocks, and ends them with END.
(sequence ...) of course would only do the sequential execution part of
this, like ; in Algol 60, so it wouldn't allow definitions. So sequence
could be used like progn 'compile is in Maclisp.
Jonathan
∂01-Apr-86 2109 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU LETREC (REC)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 1 Apr 86 21:09:12 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 2 APR 86 00:10:57 EST
Date: Tue, 1 Apr 1986 23:10 EST
Message-ID: <CPH.12195508714.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
To: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: LETREC (REC)
In-reply-to: Msg of 31 Mar 1986 19:59-EST from Bill Rozas <JINX%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
I think that restricting LETREC to only procedures is slightly
excessive -- one should also be allowed to use delayed (call-by-need
or call-by-name) thunks since these are also useful and do not allow
any of the cases that I think you object to.
∂01-Apr-86 2111 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU LETREC (REC)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 1 Apr 86 21:11:43 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 2 APR 86 00:10:59 EST
Date: 1 Apr 1986 23:31 EST (Tue)
Message-ID: <JINX.12195512581.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
Cc: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>,
RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: LETREC (REC)
In-reply-to: Msg of 1 Apr 1986 23:10-EST from CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU
Do we have any way in the language to specify "delayed" evaluation
except for LAMBDA? I agree DELAY is reasonable also.
∂02-Apr-86 0017 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: immutable structures
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 2 Apr 86 00:17:37 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 2 Apr 86 03:19:23 EST
Received: from tektronix by csnet-relay.csnet id ag28242; 2 Apr 86 2:48 EST
Received: by tektronix (5.31/5.14)
id AA11753; Tue, 1 Apr 86 11:03:57 PST
Received: by tekchips (5.31/5.14)
id AA24444; Tue, 1 Apr 86 11:04:18 PST
Message-Id: <8604011904.AA24444@tekchips>
To: ANDY@su-sushi.ARPA
Cc: rrrs-authors@mc.lcs.mit.edu
Subject: Re: immutable structures
In-Reply-To: Your message of Mon 31 Mar 86 10:07:51-PST.
<12195136917.17.ANDY@SU-SUSHI.ARPA>
Date: 01 Apr 86 11:04:11 PST (Tue)
From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
Andy Freeman writes:
Immutable cons structures bother me.
Every other immutable structure in Scheme has a distinct reader
syntax.
I think the idea is that QUOTE would mark structures as immutable.
...Would someone please enlighten
me and justify immutable quoted structures without resorting to
"[some] formal system is cleaner without distinguishing them" as the
best reason?
There may be some formal systems that are made cleaner by making quoted
structures immutable, but the denotational semantics certainly becomes
more complex.
I think immutable pairs are motivated by the fact that in many systems
side effects to quoted list structure alter the source code, particularly
when the code is interpreted rather than compiled. This can make it hard
to debug, so the implementors want to discourage such side effects by
calling them "errors".
If, on the other hand, side effects to quoted structure don't alter the
source code, then people get even more confused, as when a procedure
whose source code is
(lambda (flag) (let ((x '(a))) (if flag (car x) (whiznagle x))))
returns 97 when passed a true argument.
Peace, Will
∂02-Apr-86 1004 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU begin
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 2 Apr 86 09:55:54 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 2 APR 86 12:57:31 EST
Date: Wed, 2 Apr 1986 12:57 EST
Message-ID: <CPH.12195659294.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: begin
In-reply-to: Msg of 1 Apr 1986 23:51-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
I don't like the idea of extending BEGIN to allow definitions. ALGOL
needed that because it didn't have LET; we don't have that excuse.
I think that this would cause widespread use of the (to me) most
objectionable form of local DEFINE, that is, use of DEFINE where LET
is more appropriate.
I have stated my position on this: local DEFINE should be a fossil
preserved explicitly for S&ICP, just as SEQUENCE is. Given this
position, it seems unwise to alter other parts of the language to
accomodate local DEFINE.
As yet no one except Jinx has responded to me. Instead, the
discussion on DEFINE continues to extend itself into ever-new realms
of complexity.
To those of you who seem to need DEFINE: please at least give me some
argument in favor of local DEFINE rather than just ignoring me.
∂02-Apr-86 1033 JAR@MC.LCS.MIT.EDU begin
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 2 Apr 86 10:18:46 PST
Date: Wed, 2 Apr 86 13:20:44 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: begin
To: CPH@OZ.AI.MIT.EDU
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].870519.860402.JAR>
Date: Wed, 2 Apr 1986 12:57 EST
From: CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU
I don't like the idea of extending BEGIN to allow definitions. ALGOL
needed that because it didn't have LET; we don't have that excuse.
Then perhaps BEGIN should be caled something else... maybe SEQUENCE or
SEQUENTIALLY... I thought it got its name from Algol 60 and therefore
should be as much like Algol 60's begin blocks as possible... rememeber
that BEGIN in Algol 60 is primarily a binding construct, not a
sequencing construct so I thought there was a mismatch of name and
functionality here, one or the other should change... don't anyone
messages that I send on April 1 seriously. This issue has been beaten
to death and it was (& is) in poor taste for me to inflame old wounds
again.
I'm going to leave BEGIN as it is. Rather than put SEQUENCE in an
appendix, I and some others at MIT prefer that it be left in the main
part of the report as a non-essential special form, and we want to flush
the request that it "not be used in new code". (Today is April 2.) I
hope this doesn't bother anyone too strongly.
Apparently there's no consensus on any change to local DEFINE, so I'm
going to leave it as it is the the RRRS: all the definitions must appear
at the beginning; local defines are sugar for LETREC; LETREC binds
everything at the top, and does the right-hand side computations and the
assignments in an indeterminate order; LETREC permits arbitrary
expressions on the right-hand sides; a reference to any of the variables
during the evaluation of any of the right-hand sides is an error.
Jonathan
∂02-Apr-86 1051 @MC.LCS.MIT.EDU:KMP@SCRC-STONY-BROOK.ARPA begin
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 2 Apr 86 10:40:24 PST
Received: from SCRC-STONY-BROOK.ARPA by MC.LCS.MIT.EDU 2 Apr 86 13:42:10 EST
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 453247; Wed 2-Apr-86 13:32:36-EST
Date: Wed, 2 Apr 86 13:32 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: begin
To: JAR@MIT-MC.ARPA, CPH@MIT-MC.ARPA
cc: RRRS-AUTHORS@MIT-MC.ARPA
In-Reply-To: <[MC.LCS.MIT.EDU].870519.860402.JAR>
Message-ID: <860402133240.3.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Date: Wed, 2 Apr 86 13:20:44 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Date: Wed, 2 Apr 1986 12:57 EST
From: CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU
I don't like the idea of extending BEGIN to allow definitions. ALGOL
needed that because it didn't have LET; we don't have that excuse.
Then perhaps BEGIN should be caled something else... maybe SEQUENCE or
SEQUENTIALLY... I thought it got its name from Algol 60 and therefore
should be as much like Algol 60's begin blocks as possible... rememeber
that BEGIN in Algol 60 is primarily a binding construct, not a
sequencing construct so I thought there was a mismatch of name and
functionality here, one or the other should change... don't anyone
messages that I send on April 1 seriously. This issue has been beaten
to death and it was (& is) in poor taste for me to inflame old wounds
again.
I'm going to leave BEGIN as it is. Rather than put SEQUENCE in an
appendix, I and some others at MIT prefer that it be left in the main
part of the report as a non-essential special form, and we want to flush
the request that it "not be used in new code". (Today is April 2.) I
hope this doesn't bother anyone too strongly.
Apparently there's no consensus on any change to local DEFINE, so I'm
going to leave it as it is the the RRRS: all the definitions must appear
at the beginning; local defines are sugar for LETREC; LETREC binds
everything at the top, and does the right-hand side computations and the
assignments in an indeterminate order; LETREC permits arbitrary
expressions on the right-hand sides; a reference to any of the variables
during the evaluation of any of the right-hand sides is an error.
Jonathan
I didn't realize this idea of putting definitions in BEGIN was a serious
suggestion. I strongly oppose having either BEGIN or LET do this. The reason
is that it makes it impossible to write code which wants to use these
primitives for other things and doesn't have additional implications that
may be unwanted or may have implications in macros or program-writing programs
that some programmer didn't count on.
As a counter-proposal, how about a LOCALLY special form.
ie, (LOCALLY <definition>* <form>*)
∂02-Apr-86 1033 JAR@MC.LCS.MIT.EDU LETREC (REC)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 2 Apr 86 10:24:38 PST
Date: Wed, 2 Apr 86 13:26:24 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: LETREC (REC)
To: JINX@OZ.AI.MIT.EDU
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU, CPH@OZ.AI.MIT.EDU
In-reply-to: Msg of 1 Apr 1986 23:31 EST (Tue) from Bill Rozas <JINX%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
Message-ID: <[MC.LCS.MIT.EDU].870526.860402.JAR>
Date: 1 Apr 1986 23:31 EST (Tue)
From: Bill Rozas <JINX%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
Do we have any way in the language to specify "delayed" evaluation
except for LAMBDA? I agree DELAY is reasonable also.
DELAY and FORCE will be documented (non-essential) in the next report.
∂02-Apr-86 1102 JAR@MC.LCS.MIT.EDU begin
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 2 Apr 86 10:50:16 PST
Date: Wed, 2 Apr 86 13:52:10 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: begin
To: KMP@SCRC-STONY-BROOK.ARPA
cc: CPH@MC.LCS.MIT.EDU, RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Wed 2 Apr 86 13:32 EST from Kent M Pitman <KMP at SCRC-STONY-BROOK.ARPA>
Message-ID: <[MC.LCS.MIT.EDU].870557.860402.JAR>
Date: Wed, 2 Apr 86 13:32 EST
From: Kent M Pitman <KMP at SCRC-STONY-BROOK.ARPA>
I didn't realize this idea of putting definitions in BEGIN was a serious
suggestion.
Let me repeat myself. I sent the message on April 1. I hoped that the
<optional end> would cue people. It was not a serious suggestion.
I strongly oppose having either BEGIN or LET do this. The reason
is that it makes it impossible to write code which wants to use these
primitives for other things and doesn't have additional implications that
may be unwanted or may have implications in macros or program-writing programs
that some programmer didn't count on.
Too late to get it out of LET and friends, I think. Let's make BEGIN
the way to disallow define's, and leave the expansion of LET into
((LAMBDA ...) ...) as simple as it is.
As a counter-proposal, how about a LOCALLY special form.
ie, (LOCALLY <definition>* <form>*)
This is sort of what John Ramsdell was suggesting. It's also exists in
T and is written (LOCALE #F ...). But I'll appeal to conservatism and
say that not only will there not be any agreement on adding or naming
this beast, but providing a special form especially for its benefit
gives legitimacy to local DEFINE which I don't think most people want.
J.
∂02-Apr-86 1338 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU begin
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 2 Apr 86 13:26:59 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 2 APR 86 16:19:34 EST
Date: 2 Apr 1986 14:57 EST (Wed)
Message-ID: <JINX.12195681098.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Cc: CPH@MC.LCS.MIT.EDU, JAR@MC.LCS.MIT.EDU, RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: begin
In-reply-to: Msg of 2 Apr 1986 13:32-EST from Kent M Pitman <KMP at SCRC-STONY-BROOK.ARPA>
I didn't realize this idea of putting definitions in BEGIN was a serious
suggestion. I strongly oppose having either BEGIN or LET do this. The reason
is that it makes it impossible to write code which wants to use these
primitives for other things and doesn't have additional implications that
may be unwanted or may have implications in macros or program-writing programs
that some programmer didn't count on.
As a counter-proposal, how about a LOCALLY special form.
ie, (LOCALLY <definition>* <form>*)
The main reason for local DEFINE is S&ICP. If LET is just syntactic
sugar for LAMBDA, DEFINE must be allowed at top level of a LET.
Beyond that I would object strongly to disallowing DEFINE in LET since
I (and other people at MIT) use it all the time.
I think that JAR sent the message about begin at least half jokingly
(April 1st), so it should not be taken too seriously.
∂02-Apr-86 1352 JAR@MC.LCS.MIT.EDU expansion of LETREC
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 2 Apr 86 13:33:06 PST
Date: Wed, 2 Apr 86 16:35:01 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: expansion of LETREC
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].870750.860402.JAR>
I would like to put a little more detail in the report about the
distinction between the "syntactic sugar" special forms (COND etc.) and
the "primitive" or "core" ones (QUOTE IF LAMBDA BEGIN SET!). The
distinction is a good one to make even in the absence of macros. This
isn't hard to do for any of the special forms except for LETREC. The
following almost works:
(letrec ((v1 x1) (v2 x2) ...) body) ==>
(let ((v1 <unspecified>) (v2 <unspecified>) ...)
(let ((temp1 x1) (temp2 x2) ...) ;Note unspecified evaluation order
(set! v1 temp1) ;temp1 etc. are vars which don't occur free in body
(set! v2 temp2)
...
body))
But this ultimately doesn't foot the bill because it fails to say that
it is an error to reference the bound variables before they're
initialized. This is very different from the variables having
unspecified values, since if the variable has an unspecified value it
cannot be an error to access that value, even though it may be an error
to do anything with it.
Let me describe the alternative solutions that have occurred to me:
1. Say that LETREC is "almost not primitive" except for this one quirk.
That's probably the status quo position. This is bad because it
increases the number of primitives from 5 to 6, and because there are
now two variable binding constructs instead of one. LETREC is so close
to being syntactic sugar that it would be a shame if it wasn't
first-class syntactic sugar.
2. Legitimize this actually quite useful feature of creating
uninitialized locations by introducing an explicit mechanism to create
them:
2a. In MIT Scheme this is (define var). This is unacceptable
because it makes DEFINE primitive instead of syntactic sugar.
2b. Another alternative would be to have a new binding construct
[Andy, doesn't 1S have something like this?], say (LOCALS (var1 var2
...) body), which introduces uninitialized bindings. This is also
not good since it would be a shame to add a new special form, especially
one which makes LAMBDA not be the only binding construct.
3. Similar to the #2, but with a new procedure instead of a special
form. Let's call it CALL-WITH-UNINITIALIZED-PARAMETERS. This is a
procedure of one argument, which calls its procedure argument in such a
way that the procedure's parameters are uninitialized:
(call-with-uninitialized-parameters
(lambda (var1 var2 ...) body))
4. Have a procedure, say (UNINITIALIZED), which returns an object which
when stored in a variable's location causes it to be an error to access
the location. This is similar to (3), but much more powerful, since
initializedness is no longer "monotonic" - a variable which had a value
can come to not have a value if it is SET! to (UNINITIALIZED). I think
that kind of power could be dangerous although I can't say exactly why I
think so. It's like MAKUNBOUND only worse.
5. Like 4 but don't document the procedure. I don't like this because
it seems to hide something form the user -- it taunts, "I have this
feature but I won't let you use it".
6. Disallow anything besides LAMBDA-expressions on the right-hand sides.
This would mean that nothing would have to be said about it being an
error to reference the variables since there's no way that could happen
anyhow. The problem with this is that even if it's a perfectly good
idea (true of the 1975 & 1978 Schemes) no one except Bill Rozas likes
it, not even me.
7. Change to normal order evaluation. I don't think this is practical
or desirable at this point.
---
Let me know what y'all think about CALL-WITH-UNINITIALIZED-PARAMETERS.
If you like it (I kind of do) then try to think of a name for it.
Please overlook the question of what happens when you pass it CONS as an
argument. We can just say that it's an error to pass it any primitive
procedure, since they all presumably reference their parameters. If you
don't like it then please defend position number 1 so that I feel more
comfortable documenting it.
Jonathan.
∂02-Apr-86 1354 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU begin
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 2 Apr 86 13:53:51 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 2 APR 86 16:13:59 EST
Date: Wed, 2 Apr 1986 14:32 EST
Message-ID: <CPH.12195676610.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: begin
In-reply-to: Msg of 2 Apr 1986 13:20-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
Date: Wednesday, 2 April 1986 13:20-EST
From: Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
Then perhaps BEGIN should be caled something else... maybe SEQUENCE or
SEQUENTIALLY... I thought it got its name from Algol 60 and therefore
should be as much like Algol 60's begin blocks as possible...
This is one reason why I objected to this name at Brandeis. But it is
clearly too late to change it now.
don't anyone messages that I send on April 1 seriously.
I guess the joke's on me... I didn't catch that one (although your
other message was pretty obvious).
∂02-Apr-86 1508 NET-ORIGIN@MC.LCS.MIT.EDU expansion of LETREC
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 2 Apr 86 15:06:36 PST
Received: from ZERMATT.LCS.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 2 APR 86 17:49:22 EST
Received: from ASPEN.LCS.MIT.EDU by MIT-ZERMATT.ARPA via CHAOS with CHAOS-MAIL id 30141; Wed 2-Apr-86 17:37:39-EST
Date: Wed, 2 Apr 86 17:37 EST
From: Robert Halstead <rhh@MIT-VAX.ARPA>
Subject: expansion of LETREC
To: JAR@MIT-MC.ARPA
cc: RRRS-AUTHORS@MIT-MC.ARPA
In-Reply-To: <[MC.LCS.MIT.EDU].870750.860402.JAR>
Message-ID: <860402173745.5.RHH@ASPEN.LCS.MIT.EDU>
I have some misgivings about your solution number (3), involving
CALL-WITH-UNINITIALIZED-PARAMETERS: what would it mean to apply this to
a procedure of the form (LAMBDA (X . Y) ...)? Also, I am not entirely
sure I am ecstatic about supplying a procedure such as C-W-U-P for
people to use directly -- I guess my concern is more that I see no
utility for it other than as an expository device for explaining LETREC,
rather than as something people might want to use explicitly. Finally,
I think there might be some resistance to defining LETREC in terms of a
side-effect primitive such as SET!, even if such a definition is
possible, but I guess I can let the people who would resist speak for
themselves.
If you use it, how about APPLY-TO-UNINITIALIZED-VALUES as an alternative
name? -b.
∂02-Apr-86 1625 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU expansion of LETREC
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 2 Apr 86 16:25:28 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 2 APR 86 19:06:10 EST
Date: Wed, 2 Apr 1986 19:05 EST
Message-ID: <CPH.12195726397.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: expansion of LETREC
In-reply-to: Msg of 2 Apr 1986 16:35-EST from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>
I favor position number 1. The reason: it is a relatively simple
solution to what seems a relatively unimportant issue.
I think that implementors are free to use a procedure like
UNINITIALIZED internally, thus preserving LAMBDA as the sole binding
operator. MIT Scheme does just this. The syntax for LETREC (and
optionally, LET) provides the user with a means of creating
uninitialized variables.
∂03-Apr-86 0737 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA non-list arguments
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 3 Apr 86 07:36:50 PST
Received: from GODOT.THINK.COM by MC.LCS.MIT.EDU 3 Apr 86 10:37:17 EST
Received: from katherine by GODOT.THINK.COM via CHAOS; Thu, 3 Apr 86 10:34:56 est
Date: Thu, 3 Apr 86 10:36 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: non-list arguments
To: rhh@MIT-VAX.ARPA, JAR@MIT-MC.ARPA
Cc: SCHEME@MIT-MC.ARPA, t-discussion@YALE.ARPA, gls@THINK-AQUINAS.ARPA
In-Reply-To: <860401152644.7.RHH@ASPEN.LCS.MIT.EDU>
Message-Id: <860403103623.3.GLS@THINK-KATHERINE.ARPA>
I haven't checked the manuals for T or Scheme but it was certainly the
intent that the list passed to APPLY is unrelated to the list that a
rest-parameter gets bound to. The rest-list should always be freshly
consed, so e.g. the procedure LIST is equivalent to (LAMBDA X X). The
last argument to APPLY must be a proper list. I think Common Lisp takes
the same stance.
A quick scan of the Common Lisp book leaves the question unresolved;
maybe Guy Steele could comment.
This question came up recently on the Common-Lisp mailing list. The
unofficial consensus, as I understood it, was that the book is vague on
this point and requires correcting; that the last argument to APPLY
should be a proper list; and that a list passed as an argument to APPLY
might or might not share list structure with an eventual &REST argument
resulting from the application.
--Guy
∂03-Apr-86 0822 @MC.LCS.MIT.EDU:gls@THINK-AQUINAS.ARPA begin
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 3 Apr 86 08:21:55 PST
Received: from GODOT.THINK.COM by MC.LCS.MIT.EDU 3 Apr 86 11:19:31 EST
Received: from katherine by GODOT.THINK.COM via CHAOS; Thu, 3 Apr 86 11:06:45 est
Date: Thu, 3 Apr 86 11:08 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: begin
To: KMP@SCRC-STONY-BROOK.ARPA, JAR@MIT-MC.ARPA, CPH@MIT-MC.ARPA
Cc: RRRS-AUTHORS@MIT-MC.ARPA, gls@THINK-AQUINAS.ARPA
In-Reply-To: <860402133240.3.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Message-Id: <860403110814.6.GLS@THINK-KATHERINE.ARPA>
Date: Wed, 2 Apr 86 13:32 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
...
I didn't realize this idea of putting definitions in BEGIN was a serious
suggestion. I strongly oppose having either BEGIN or LET do this. The reason
is that it makes it impossible to write code which wants to use these
primitives for other things and doesn't have additional implications that
may be unwanted or may have implications in macros or program-writing programs
that some programmer didn't count on.
As a counter-proposal, how about a LOCALLY special form.
ie, (LOCALLY <definition>* <form>*)
The Common Lisp committee went through this issue, rather painfully. At
one point I had proposed that PROGN, and any implicit PROGN (such as
COND clauses) allow DECLARE forms at the front. This was roundly and
soundly booed, and LOCALLY emerged from the fracas.
--Guy
∂03-Apr-86 0929 @MC.LCS.MIT.EDU:hudak@YALE.ARPA Re: expansion of LETREC
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 3 Apr 86 09:28:46 PST
Received: from yale-bulldog by MC.LCS.MIT.EDU 3 Apr 86 12:28:33 EST
Received: by Yale-Bulldog.YALE.ARPA; 3 Apr 86 11:59:19 EST (Thu)
Date: 3 Apr 86 11:59:19 EST (Thu)
From: Paul Hudak <hudak@YALE.ARPA>
Message-Id: <8604031659.AA05511@Yale-Bulldog.YALE.ARPA>
Subject: Re: expansion of LETREC
To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-Reply-To: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>, Wed, 2 Apr 86 16:35:01 EST
Off-hand it seems odd that one can't write LETREC in Scheme -- the
problem, of course, is that special forms are usually equated with
macros, which have limited transformation capabilities. One CAN define
the semantics of LETREC in Scheme by the following transformation:
Let xi' be like xi except that all (free) occurrences of vi are
replaced with (force vi); similarly for body'. Then:
(letrec ((v1 x1) (v2 x2) ...) body) ==>
(let ((v1 (delay (error ...))) (v2 (delay (error ...))) ...)
(let ((temp1 x1') (temp2 x2') ...) ;unspecified evaluation order
(set! v1 (delay temp1)) ;tempi don't occur free in body
(set! v2 (delay temp2))
...
body'))
Compare this with your:
(let ((v1 <unspecified>) (v2 <unspecified>) ...)
(let ((temp1 x1) (temp2 x2) ...) ;unspecified evaluation order
(set! v1 temp1) ;tempi don't occur free in body
(set! v2 temp2)
...
body))
I haven't thought about this in detail, like how it interacts with
CALL-WITH-CURRENT-CONTINUATION, but off-hand it seems to avoid the
proliferation of primitive special forms (your solution 1) or primitive
procedures (your solutions 2-5) yet is precise in the semantics (I think).
-Paul
∂03-Apr-86 1139 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU expansion of LETREC
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 3 Apr 86 11:35:28 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 3 APR 86 14:35:10 EST
Date: 3 Apr 1986 14:12 EST (Thu)
Message-ID: <JINX.12195935178.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Paul Hudak <hudak@YALE.ARPA>
Cc: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>, RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: expansion of LETREC
In-reply-to: Msg of 3 Apr 1986 11:59-EST from Paul Hudak <hudak at YALE.ARPA>
Please ignore previous message. Somehow I did not notice the
following lines (parser must have failed)
Let xi' be like xi except that all (free) occurrences of vi are
replaced with (force vi); similarly for body'. Then:
∂03-Apr-86 1154 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU expansion of LETREC
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 3 Apr 86 11:50:41 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 3 APR 86 14:33:58 EST
Date: 3 Apr 1986 14:11 EST (Thu)
Message-ID: <JINX.12195934954.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Paul Hudak <hudak@YALE.ARPA>
Cc: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>, RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: expansion of LETREC
In-reply-to: Msg of 3 Apr 1986 11:59-EST from Paul Hudak <hudak at YALE.ARPA>
Is your DELAY "forced" automatically on reference? If not I don't
understand how this works. Neither of the 2 versions of DELAY that
I'm familiar with (automatic forcing by appropriate primitives and
explicit forcing) would solve the problem. If it is forced on
reference then it seems pretty useless (useful only for this?) since
one of the crucial features of DELAY is that CONS does not force it,
so streams can be built on top of it.
∂04-Apr-86 1334 @MC.LCS.MIT.EDU:Pase.CCS@DOCKMASTER.ARPA Scheme for the Atari ST
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 4 Apr 86 13:34:26 PST
Received: from DOCKMASTER.ARPA by MC.LCS.MIT.EDU 4 Apr 86 16:23:17 EST
Date: Fri, 4 Apr 86 00:59 EST
From: Bill Pase <Pase@DOCKMASTER.ARPA>
Subject: Scheme for the Atari ST
To: scheme@MIT-MC.ARPA
Message-ID: <860404055925.041933@DOCKMASTER.ARPA>
Does anyone know if Scheme is available for the Atari ST? I know there
are versions for the IBMPC and the Macintosh. It wouIt would seem
especially with the later that an Atari version should be easy. Does
anyone have any plans to develop it? /bill
∂04-Apr-86 1413 @MC.LCS.MIT.EDU:KWH@AI.AI.MIT.EDU LETREC (REC)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 4 Apr 86 14:13:05 PST
Received: from AI.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 4 APR 86 16:24:51 EST
Date: Fri, 4 Apr 86 09:31:19 EST
From: Ken Haase <KWH@AI.AI.MIT.EDU>
Subject: LETREC (REC)
To: JINX@OZ.AI.MIT.EDU
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of 1 Apr 1986 09:47 EST (Tue) from Bill Rozas <JINX%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
Message-ID: <[AI.AI.MIT.EDU].23941.860404.KWH>
Date: 1 Apr 1986 09:47 EST (Tue)
From: Bill Rozas <JINX%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
To: Ken Haase <KWH at AI.AI.MIT.EDU>
cc: RRRS-AUTHORS at MC.LCS.MIT.EDU
Re: LETREC (REC)
Unfortunately it is not ill defined. A simple "operational"
description (like the one in the currentl version of RRRS) describes
what is legal and what is not. I view this operational description as
a crock, and the only way that I can see to restrict the use of LETREC
to reasonable cases is to "over-restrict" it.
The problem is that this particular over restriction really diminishes
the power of the language; no clever macrology (in the current RRRS)
is going to allow general higher order functions to generate recursive
functions. (By general, I mean higher order functions which don't
specifically expect to generate recursive functions).
Note that the error is not unbound variable. The variable is bound,
since the expressions are evaluated in an environment where the names
are bound. At best it is unassigned, but this implies that there are
side effects going on, which I don't like.
I meant unassigned. I think that in any implementation-oriented
explanation, you may have to resort to side effects to explain
what is going on. Even if you characterize LETREC with delays,
it seems to me that you will still have an understood side-effect
lurking inside of the delay.
∂04-Apr-86 1448 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU LETREC (REC)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 4 Apr 86 14:43:08 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 4 APR 86 17:43:10 EST
Date: 4 Apr 1986 10:47 EST (Fri)
Message-ID: <JINX.12196159853.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Ken Haase <KWH@AI.AI.MIT.EDU>
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
Subject: LETREC (REC)
In-reply-to: Msg of 4 Apr 1986 09:31-EST from Ken Haase <KWH at AI.AI.MIT.EDU>
The problem is that this particular over restriction really diminishes
the power of the language; no clever macrology (in the current RRRS)
is going to allow general higher order functions to generate recursive
functions. (By general, I mean higher order functions which don't
specifically expect to generate recursive functions).
This is not true. While it becomes more complicated, it is possible
to do it. I don't remember your precise example but there is a simple
trick which makes it work and satifies the constraint I like. The
trick is the same as the one used in converting the normal order Y
operator into applicative order. Questions of efficiency might arise
if there is no procedure integration or the compiler is not
able to deduce what's going on or allowed to use this information.
∂04-Apr-86 1821 @MC.LCS.MIT.EDU:ANDY@SU-SUSHI.ARPA Immutable code and quoted data
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 4 Apr 86 18:07:49 PST
Received: from SU-SUSHI.ARPA by MC.LCS.MIT.EDU 4 Apr 86 21:09:21 EST
Date: Fri 4 Apr 86 15:08:28-PST
From: Andy Freeman <ANDY@SU-SUSHI.ARPA>
Subject: Immutable code and quoted data
To: rrrs-authors@MC.LCS.MIT.EDU
Message-ID: <12196240218.45.ANDY@SU-SUSHI.ARPA>
Summary:
1. Immutable structures raise lots of issues in the reader and other places
that should be settled before they are added to the language.
2. Interpreters must copy the source, unless ....
3. Side-effects on quote'd structures really aren't different from
other things the language must have.
4. Immutable quoted structures might be acceptable (and may even be a good
idea) if everything is done right; it isn't yet.
Andy Freeman (me) wrote:
Immutable cons structures bother me.
Every other immutable structure in Scheme has a distinct reader
syntax.
Will Clinger replied:
I think the idea is that QUOTE would mark structures as immutable.
Jonathan's proposal was that QUOTE mark structures in code as
immutable, but QUOTE isn't external syntax for immutable. (I should
have said distinct EXTERNAL syntax instead of reader syntax.) The
value of (read)ing (quote (a b)) is not the same as (read)ing (a b);
(write '(a b)) has the same output that (write (list 'a 'b)) does.
JAR's reply to my objection is that write and read lose address
information so why shouldn't they be allowed to lose the immutability
bit? Accepting this point raises the question, should read return
mutable structures? (I believe the answer is no.) If not, then every
immutable structure has the obvious external syntax and no mutable
structure has a reader syntax. (Requiring write's arguments to be
immutable structures is going too far.)
Everything that can be quoted will need an immutable counterpart and
it seems arbitrary to restrict immutable structures to the domain of
the interpreter. In other words, not only is immutable? necessary,
but so is immutable-cons, immutable-vector, and immutable-string. (To
put it another way, many structures will require mutable ones as
well.) We also need to decide whether the arguments to the immutable
constructors can be mutable. (I don't think they can be.)
Will Clinger continues:
I think immutable pairs are motivated by the fact that in many systems
side effects to quoted list structure alter the source code, particularly
when the code is interpreted rather than compiled. This can make it hard
to debug, so the implementors want to discourage such side effects by
calling them "errors".
Not that I've done this right either, but since compilation must copy
the source code, interpreters should behave as if they are using a
copy of the source. This has other advantages. For example, is it
legal for a program to modify its source to affect its behavior or for
the source to be circular? (I think not.)
If all of the above is accepted (read returns immutable structures and
immutable structures can't contain mutable ones) and code and quoted
data must be immutable and acyclic, then the copy seems unnecessary.
Note that this last position is extreme; both code and quoted data are
immutable. JAR's proposal was that quoted data should be immutable.
I'd like immutable code. The issues are separate. Currently Scheme
has mutable code and quoted data. I believe that Scheme should change
to at least "immutable" code, which can be accomplished by copying the
source. (No, it actually doesn't require new data types or
operations.) JAR proposes immutable quoted data, which can be
accomplished in the ways he described with the additions I suggest.
True constant data structures, such as JAR proposes, are rare. Apart
from functional and logic languages, like FP and Prolog (and they're a
special case in Prolog), ML is the only language I know of with
constant data. (c++ may have constant structures, but c definitely
doesn't.)
I don't see side effects on quoted structure as being something odd;
QUOTE is a convenient short-hand, but it isn't a syntax for constants.
-andy
@begin(tangent)
Obviously the following procedure can return 97.
(let ((x (list 'a))) ; procedure-a
(lambda (flag)
(if flag (set-car! x flag)
(car x))))
On the other hand, many of you object to the same behavior by the
following procedure
(let ((x '(a))) ; procedure-b
(lambda (flag)
(if flag (set-car! x flag)
(car x))))
or an equivalent one.
(lambda (flag) ; procedure-c
(let ((x '(a)))
(if flag (set-car! x flag)
(car x))))
I believe procedure-b and procedure-c are the same because I believe
that quote'd structures are built at load time (or possibly read or
compile time). In other words, I believe that the following must be
#t.
(let ((x (lambda ()
(lambda () '(a)))))
(eq? ((x)) ((x))))
@end(tangent)
-------
∂04-Apr-86 1943 JAR@MC.LCS.MIT.EDU Immutable code and quoted data
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 4 Apr 86 19:23:20 PST
Date: Fri, 4 Apr 86 22:25:15 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: Immutable code and quoted data
To: ANDY@SU-SUSHI.ARPA
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Fri 4 Apr 86 15:08:28-PST from Andy Freeman <ANDY at SU-SUSHI.ARPA>
Message-ID: <[MC.LCS.MIT.EDU].874458.860404.JAR>
The area of immutable data for Scheme is a good one for experimentation.
But I don't think Scheme should take a stand on this subject at this
time. The trick is to phrase the report in such a way as to allow
latitude for people to play around with these ideas.
My main motivation at this point (now that I see there's no consensus)
is that I don't want anyone's implementations to have to change in order
to support EQV? and QUOTE as defined in the Scheme report. My proposed
EQV? and QUOTE specifications ALLOW implementations to create immutable
structure and have EQV? (and even EQ?) compare the contents of immutable
structure; but they don't REQUIRE them to. It is probably compatible
with most Schemes in existence, because it is so noncommittal.
It sounds like you're trying to make the language more concrete. If a
stand is taken one way or another, then no matter which stand is taken,
some implementations will have to change. If quoted structure must be
mutable, then T, and I suspect some other implementations, including any
implementation embedded in Maclisp or Common Lisp, will have to go to
some trouble to avoid using the obvious existing mechanisms. If it must
be immutable, you'll also be cursed by implementors who need to add
immutable types and more complicated type checking.
Saying that it is an error if structure created by QUOTE is clobberred
is much weaker than saying either that implementations must have an
IMMUTABLE? predicate or that quoted structure must be mutable. Errors
do not have to be detected.
I don't see why it makes sense to distinguish interpretation from
compilation. Scheme has no way to distinguish these situations.
Remember that there is no EVAL, and there's no guarantee that the
mechanism which causes programs to be executed uses READ - it parses the
program somehow, but READ has nothing to do with that.
I think it would be reasonable to argue that READ should be allowed to
return immutable structure, but I'm not going to do so, because I think
some people disagree and I don't feel strongly about it. But again,
QUOTE and READ are unrelated, since there's no EVAL. It doesn't make
sense to talk about "copying the source" since source only exists in
files. If there were an EVAL, I would certainly want it to copy both the
code and the quoted structure (if those things were mutable), to ensure
compatibility between EVAL and transduced (compiled or whatever) code; I
think we agree there.
I agree that if immutable structure exists, then some mechanism besides
QUOTE should exist to create it. (Maclisp's solution is to have a
single function, PURCOPY, which makes a pure copy of an impure
structure.) I also agree that immutable structure shouldn't contain
mutable structure and shouldn't be circular (although I doubt that there
would be consensus on these questions - various functional languages out
there let one create circular immutable objects using LETREC). But I
wouldn't want to force these things on implementors; again, this area is
too borderline and experimental.
(A propos rarity of constant data structures: Algol 68 certainly has all
kinds of constant data. Also, I was under the impression that C
implementations were allowed to put in-line strings constants in pure
(text) memory.)
Jonathan
∂04-Apr-86 1943 JAR@MC.LCS.MIT.EDU Immutable code and quoted data
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 4 Apr 86 19:29:33 PST
Date: Fri, 4 Apr 86 22:31:26 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: Immutable code and quoted data
To: ANDY@SU-SUSHI.ARPA
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Fri 4 Apr 86 15:08:28-PST from Andy Freeman <ANDY at SU-SUSHI.ARPA>
Message-ID: <[MC.LCS.MIT.EDU].874480.860404.JAR>
Date: Fri 4 Apr 86 15:08:28-PST
From: Andy Freeman <ANDY at SU-SUSHI.ARPA>
I believe procedure-b and procedure-c are the same because I believe
that quote'd structures are built at load time (or possibly read or
compile time). ...
I believe that procedure-b and procedure-c are illegal because I believe
that quoted structures are built in the user's mind (which the machine
shouldn't be mucking around with). Weird "times" shouldn't come into
question here ...
Jonathan
∂06-Apr-86 2037 @MC.LCS.MIT.EDU:wagle%indiana.csnet@CSNET-RELAY.ARPA LETREC (REC)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 6 Apr 86 20:33:24 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 6 Apr 86 23:35:16 EST
Received: from indiana by csnet-relay.csnet id a025875; 6 Apr 86 23:34 EST
Date: Sun, 6 Apr 86 00:13:42 est
From: Perry Wagle <wagle%indiana.csnet@CSNET-RELAY.ARPA>
To: rrrs-authors@mc.lcs.mit.edu
Subject: LETREC (REC)
/**** iuvax:scheme-rrrs / iuvax!wagle / 12:50 am Apr 2, 1986 ****/
> iuvax:scheme-rrrs / iuvax!JINX%OZ.AI.MIT.EDU@xx.lcs / 11:41 pm Apr 1, 1986
> As you probably know by now, there is a feature that I REALLY dislike about
> LETREC (REC), namely that LETREC allows non-lambda expressions in the
> binding list. I would like to make this optional and make the standard
> allow only lambda expressions. Is there a lot of opposition to this?
> ...
LAMBDA expressions aren't the only expressions to return closures. Except
for trivial cases, there is no way to know at compile-time whether or not an
expression is going to return a closure or not. I definitely demand that I
be allowed to use "function constructors" in the RHS of letrec bindings
(that is functions that return functions).
Perry Wagle, Indiana University, Bloomington Indiana.
...!ihnp4!inuxc!iuvax!wagle (USENET)
wagle@indiana (CSNET)
wagle%indiana@csnet-relay (ARPA)
∂07-Apr-86 0858 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: expansion of LETREC
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 7 Apr 86 08:58:32 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 7 Apr 86 12:00:16 EST
Received: from indiana by csnet-relay.csnet id aa00192; 7 Apr 86 11:25 EST
Date: Mon, 7 Apr 86 00:26:03 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: rrrs-authors@mc.lcs.mit.edu
Subject: Re: expansion of LETREC
I favor saying that "one possible" definition of LETREC is the
one given earlier, or even the following:
(letrec ((x v) ...) e ...)
=>
(let ((x 'any) ...)
(set! x v) ...
e ...)
Neither definition catches all the possible errors, but we have
already said that not all errors need be caught.
Of course, any implementation would be free to check for errors
before performing this transformation!
∂07-Apr-86 0901 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: expansion of LETREC (hmmm)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 7 Apr 86 09:01:43 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 7 Apr 86 12:00:41 EST
Received: from indiana by csnet-relay.csnet id ab00192; 7 Apr 86 11:26 EST
Date: Mon, 7 Apr 86 00:43:26 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: rrrs-authors@mc.lcs.mit.edu
Subject: Re: expansion of LETREC (hmmm)
I have had two people express great surprise and chagrin that
LETREC does not guarantee left-to-right evaluation as does LET*.
(One is a veteran in computer science; the other is an economist
with substantial programming experience in a few unmentionable
languages. Both were new to Scheme.) They both wanted to use LET
when there is no constraint on ordering, LET* when the ordering
is sequential, and LETREC when there is recursion or circularity.
Both felt that they should be able to use LETREC wherever they
could have used LET*, (unless they needed to use a variable with
a conflicting name outside of the form). In other words, they
felt that LET, LET* and LETREC formed (or should form) a linear
sequence, each more powerful (in a sense) than the last. They
felt that the restrictions on LETREC were arbitrary and useless.
When I showed them the definitions of LET, LET* and LETREC (the
latter in terms of let and set!), both pointed out that it would
be trivial to support this functionality. In other words, they
wanted the definition for LETREC given in my last note:
(letrec ((x v) ...) e ...)
=>
(let ((x 'any) ...) (set! x v) ... e ...)
This issue, of course, does not concern those who avoid anything
but lambda expressions in LETREC.
I'm not sure I see any harm in this definition of LETREC, but I
haven't come to any real conclusion on this matter. It certainly
has the merits of reducing confusion and making the writing of the
RRRS easier.
∂07-Apr-86 0906 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: Immutable code and quoted data
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 7 Apr 86 09:05:48 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 7 Apr 86 12:02:58 EST
Received: from indiana by csnet-relay.csnet id ae00192; 7 Apr 86 11:27 EST
Date: Mon, 7 Apr 86 02:23:45 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: rrrs-authors@mc.lcs.mit.edu
Subject: Re: Immutable code and quoted data
I agree that the report should not constrain implementations
one way or another on the quote/mutable issue. There are
reasonable arguments on both sides.
On the immutable side, it can be more efficient in terms of
garbage collection and virtual memory if an implementation
is allowed to put quoted structures in read-only memory.
On the mutable side, it can be quite useful for quote to
produce mutable structures to share or retain state. For
example, consider the following implementation of "once",
presumably as a macro, where "(once e)" evalutates "e" only
once and thereafter returns the same value:
(once e) =>
(let ([x '(any . #!false)]) ; x not appearing in e
(unless (cdr x)
(set-car! x e)
(set-cdr! x #!true))
(car x))
A perverse example using once:
(begin
(define foo (lambda (x) (once x)))
(foo 3)
(foo 4)) => 3
The same sort of idea can be used for "own" variables.
Things get even stranger when quote is used to introduce the
same (identical) structure in two separate places, for some
sort of communication purposes. People here have actually
done this, although it causes problems with printing object
code in the absense of a hashing printer.
∂07-Apr-86 0908 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA efficiency vs functionality
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 7 Apr 86 09:08:43 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 7 Apr 86 12:03:31 EST
Received: from indiana by csnet-relay.csnet id af00192; 7 Apr 86 11:28 EST
Date: Mon, 7 Apr 86 02:53:41 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: rrrs-authors@mc.lcs.mit.edu
Subject: efficiency vs functionality
A letter to the editor.
After sending my last note I got to thinking about how many
arguments for or against a particular feature have been based
on how difficult efficient implementation becomes. Decisions
are often made by weighing functionality against efficiency
(as in the splitting/coalescing discussion).
It seems that the early development of Scheme was not affected
by efficiency arguments, otherwise who would have first-class
closures or continuations? Would we like Scheme as much today
if the efficiency trade-offs had been factored in? Would we
have bothered to learn how to implement first-class closures
and continuations efficiently if we did not have them in our
language?
Sure, we want to give implementors a fair chance to compete in
speed with other languages, but we may be making it a little to
easy on them. At the very least, the decisions should be along
the lines of feasibility of efficient implementation, not ease
of efficient implementation. We should never make life harder
for the user to make life easier for the implementor.
Tomorrow's editorial topic: the effect of "historical reasons,"
"existing documentation," and "1,000,000 lines of existing code"
on language design and standardization.
∂07-Apr-86 1338 @MC.LCS.MIT.EDU:GJS%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Re: expansion of LETREC (hmmm)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 7 Apr 86 13:37:44 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 7 APR 86 16:37:05 EST
Date: Mon 7 Apr 86 16:31:58-EST
From: "Gerald Jay Sussman" <GJS%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
Subject: Re: expansion of LETREC (hmmm)
To: dyb%indiana.csnet@CSNET-RELAY.ARPA
cc: rrrs-authors@MC.LCS.MIT.EDU
In-Reply-To: Message from "Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>" of Mon 7 Apr 86 12:05:14-EST
Message-ID: <12197009084.61.GJS@OZ.AI.MIT.EDU>
...they
felt that LET, LET* and LETREC formed (or should form) a linear
sequence, each more powerful (in a sense) than the last.
I think that that is wrong. LET is more powerful than LET* because
one can make LET* by nesting LETs but you cannot make LET easily from
LET*. Sequential methods are often more convenient than parallel
ones, but they are inessential. On the other hand, your
implementation of LETREC:
(letrec ((x v) ...) e ...)
=>
(let ((x 'any) ...) (set! x v) ... e ...)
certainly looks pretty good to me. The question is whether we want to
specify the order of assignment as being the same as the order of the
expressions in the LETREC. I see the same problems arising with
internal definitions (being just a syntax for a LETREC form). I
suppose that I can be moved either way.
-------
∂07-Apr-86 1343 @MC.LCS.MIT.EDU:GJS%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Re: Immutable code and quoted data
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 7 Apr 86 13:42:25 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 7 APR 86 16:39:03 EST
Date: Mon 7 Apr 86 16:34:12-EST
From: "Gerald Jay Sussman" <GJS%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
Subject: Re: Immutable code and quoted data
To: dyb%indiana.csnet@CSNET-RELAY.ARPA
cc: rrrs-authors@MC.LCS.MIT.EDU
In-Reply-To: Message from "Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>" of Mon 7 Apr 86 12:09:50-EST
Message-ID: <12197009491.61.GJS@OZ.AI.MIT.EDU>
I dunno... I think that quoted structure should be immutable...
I think that we should think of quotation as as syntax for constants.
-------
∂07-Apr-86 1910 @MC.LCS.MIT.EDU:DAVID%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU expansion of LETREC (hmmm)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 7 Apr 86 19:10:42 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 7 APR 86 22:12:26 EST
Date: 7 Apr 1986 22:10 EST (Mon)
Message-ID: <DAVID.12197070633.BABYL@MIT-OZ>
From: "David A. Brown" <DAVID%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Gerald Jay Sussman <GJS%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
Cc: David%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU, dyb%indiana.csnet@CSNET-RELAY.ARPA,
rrrs-authors@MC.LCS.MIT.EDU
Subject: expansion of LETREC (hmmm)
In-reply-to: Msg of 7 Apr 1986 16:31-EST from Gerald Jay Sussman <GJS%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
Date: Monday, 7 April 1986 16:31-EST
From: Gerald Jay Sussman <GJS%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
To: dyb%indiana.csnet at CSNET-RELAY.ARPA
cc: rrrs-authors at MC.LCS.MIT.EDU
Re: expansion of LETREC (hmmm)
ReSent-Date: Mon 7 Apr 86 20:55:41-EST
ReSent-From: Eddie Gornish <DFUSER.EHG@XX.LCS.MIT.EDU>
ReSent-To: david@OZ.AI.MIT.EDU
ReSent-Message-ID: <12197057091.48.DFUSER.EHG@XX.LCS.MIT.EDU>
...they
felt that LET, LET* and LETREC formed (or should form) a linear
sequence, each more powerful (in a sense) than the last.
I think that that is wrong. LET is more powerful than LET* because
one can make LET* by nesting LETs but you cannot make LET easily from
LET*. Sequential methods are often more convenient than parallel
ones, but they are inessential. On the other hand, your
implementation of LETREC:
(letrec ((x v) ...) e ...)
=>
(let ((x 'any) ...) (set! x v) ... e ...)
certainly looks pretty good to me. The question is whether we want to
specify the order of assignment as being the same as the order of the
expressions in the LETREC. I see the same problems arising with
internal definitions (being just a syntax for a LETREC form). I
suppose that I can be moved either way.
What the hell does this mean?
∂07-Apr-86 1927 @MC.LCS.MIT.EDU:DAVID%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 7 Apr 86 19:27:10 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 7 APR 86 22:28:52 EST
Date: 7 Apr 1986 22:25 EST (Mon)
Message-ID: <DAVID.12197073434.BABYL@MIT-OZ>
From: "David A. Brown" <DAVID%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: gjs%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU, David%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU,
dyb%indiana.csnet@CSNET-RELAY.ARPA, rrrs-authors@MC.LCS.MIT.EDU
Phase-Of-The-Moon: LQ+6D.12H.38M.45S.
Sorry about accidentally replying to all of you with that last
message. Darn babyl 'r' command...
- David
∂08-Apr-86 0713 @MC.LCS.MIT.EDU:dyb%indiana.csnet@CSNET-RELAY.ARPA Re: expansion of LETREC (hmmm)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 8 Apr 86 07:13:41 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 8 Apr 86 09:43:01 EST
Received: from indiana by csnet-relay.csnet id ab11840; 8 Apr 86 9:37 EST
Date: Tue, 8 Apr 86 00:31:16 est
From: Kent Dybvig <dyb%indiana.csnet@CSNET-RELAY.ARPA>
To: gjs@mc.lcs.mit.edu
Subject: Re: expansion of LETREC (hmmm)
Cc: rrrs-authors@mc.lcs.mit.edu
...they
felt that LET, LET* and LETREC formed (or should form) a linear
sequence, each more powerful (in a sense) than the last.
I think that that is wrong. LET is more powerful than LET* because
one can make LET* by nesting LETs but you cannot make LET easily from
LET*. Sequential methods are often more convenient than parallel
ones, but they are inessential.
I think that LET from LET* is easy, though certainly not as easy as
the other way around:
(let ((x v) ...) e ...)
=>
(let* ((y v) ...) ; y not appearing in subsequent v or e
(let* ((x y) ...) e ...))
(This definition is not so silly as it might seem, since it offers
a straightforward sequential implementation of LET.)
In any case, with simple alpha-substitution LET* can simulate LET,
and LET* will enforce sequentiality constraints while LET will not.
Yes, this "sense" in which LET* is more powerful than LET is just
convenience and nothing more, but I think most people's perception
of "power" boils down to a measure of convenience.
∂08-Apr-86 1609 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Where'd all that mail come from??!!
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 8 Apr 86 16:08:34 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 8 Apr 86 19:10:28 EST
Received: from ti-csl by csnet-relay.csnet id ad17635; 8 Apr 86 18:53 EST
Received: by tilde id AA08129; Tue, 8 Apr 86 16:45:29 cst
Date: Tue 8 Apr 86 16:38:59-CST
From: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Where'd all that mail come from??!!
To: RRRS-Authors%MIT-MC@CSNET-RELAY.ARPA
Cc: Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
Message-Id: <12197283428.47.BARTLEY@CSC60>
I have a few comments on the flood of suggestions and counter-
suggestions that have accumulated in my mailbox while I've been gone
the last two weeks.
-- On embedded DEFINEs: I agree with CPH that these should be
considered fossils preserved in the standard for the benefit of
readers of S&ICP. They should be understood as a stylistic
alternative to LETREC and thus defined in terms of NAMED-LAMBDA (or
its equivalent). JAR seems to have struck the right balance in his
suggested consensus.
-- On LETREC: Non-LAMBDA expressions must be permitted. It detracts
from the aesthetics of first-classness of procedures to say that
(LETREC ((FOO (LAMBDA (X) ...)) ...) ...)
is OK but the following is not:
(LETREC ((FOO (LET ((Y 3))
(LAMBDA (X) ...))) ...) ...)
-- On boolean constants: #T and #F look like improvements to me, but I
hate to have them and #!TRUE and #!FALSE both. I also hate to make
existing programs and implementations obsolete by eliminating #!TRUE
and #!FALSE. Is there a proposal to have a family of constants using
the `#name' convention instead of the `#!name' convention? Why? I
vote that we leave #!TRUE and #!FALSE alone.
-- On variations of LET: I vote against the (LET ((VAR)) ...) form on
the grounds that LAMBDA should be the only binding primitive for
lexical variables.
-- On case-sensitive symbols: I truly sympathize with Dyb, but must
vote for case insensitivity. I accept that this is an issue, like
choice of editors, that is as much religion as anything else, but his
proposal is too sweeping a change.
My sympathy for case sensitivity comes from wanting to have debuggers
and other programming environment tools that preserve as much as
possible of my typein, including non-essential details like the case
of symbols and the location of comments. One technique I've
considered for the former works like this:
A symbol token is interned in a case-sensitive way, but each symbol
object contains a reference to the equivalent case-insensitive
(canonicalized) symbol (which may be a self-reference). EQ? knows to
compare the contained references rather than the pointers themselves.
The printers have the choice of displaying either pname. I haven't
tried this hack, but it seems to be acceptable within the definition
of most Lisps, so perhaps someone else has.
-- On efficiency vs. functionality: Dyb has an interesting point about
where Scheme might be today if the Founding Fathers had concerned
themselves with efficiency at too early a stage. I would counter by
arguing that the very attempt to standardize Scheme, which is
motivated by the present and pending existence of several
implementations, marks the transition from `experimental' language to
`production' language for many of us. As I've heard GJS remark, maybe
it's time to invent yet another language for all these new ideas and
let Scheme remain what it is!
Regards,
David Bartley
-------
∂08-Apr-86 1806 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@mc.lcs.mit.edu Where'd all that mail come from??!!
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 8 Apr 86 18:06:26 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 8 Apr 86 21:08:18 EST
Received: from mc.lcs.mit.edu by CSNET-RELAY.ARPA id a018770; 8 Apr 86 21:03 EST
Date: 8 Apr 1986 20:57 EST (Tue)
Message-ID: <JINX.12197319606.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@xx.lcs.mit.edu>
To: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Cc: RRRS-Authors%MIT-MC@CSNET-RELAY.ARPA
Subject: Where'd all that mail come from??!!
In-reply-to: Msg of 8 Apr 1986 17:38-EST from David Bartley <Bartley%ti-csl.csnet at CSNET-RELAY.ARPA>
-- On embedded DEFINEs: I agree with CPH that these should be
considered fossils preserved in the standard for the benefit of
readers of S&ICP. They should be understood as a stylistic
alternative to LETREC and thus defined in terms of NAMED-LAMBDA (or
its equivalent). JAR seems to have struck the right balance in his
suggested consensus.
I disagree that DEFINE is a fossil. I accept that LETREC is the
essential form, but I will continue to use DEFINE (as most people at
MIT, including CPH, will) since it provides (to me) a much better
syntax. Using DEFINE is no worse than using REC, which is not
essential, and which I abhor.
-- On LETREC: Non-LAMBDA expressions must be permitted. It detracts
from the aesthetics of first-classness of procedures to say that
(LETREC ((FOO (LAMBDA (X) ...)) ...) ...)
is OK but the following is not:
(LETREC ((FOO (LET ((Y 3))
(LAMBDA (X) ...))) ...) ...)
While it is clear that this is the consensus (which I will abide by),
I don't agree with your argument. It has nothing to do with whether
procedures are first class or not. In the same way that the SET!
special form restricts its "second argument" to be a variable (and
nobody complains about this), the LETREC special form could restrict
the bindings to be lambda expressions. At any rate, your argument
goes both ways. There is something fundamentally different between
procedures and anything else because
(letrec ((fact (lambda (n) (if (= n 0) 1 (* n (fact (-1+ n)))))))
fact)
works, yet
(letrec ((a-circular-list (cons 'a a-circular-list)))
a-circular-list)
does not.
I only use letrec (actually internal define, but they are equivalent)
with values which are lambda-expressions. And I think that allowing
things like
(letrec ((frob (cons 'a (lambda () frob))))
frob)
is a very bad pun.
Note that the original Scheme system (Scheme 75) only allowed lambda
expressions as the value expressions in LABELS forms.
∂08-Apr-86 2153 JAR@MC.LCS.MIT.EDU expansion of LETREC
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 8 Apr 86 21:53:32 PST
Date: Wed, 9 Apr 86 00:55:30 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: expansion of LETREC
To: dyb%indiana.csnet@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Mon 7 Apr 86 00:26:03 est from Kent Dybvig <dyb%indiana.csnet at CSNET-RELAY.ARPA>
Message-ID: <[MC.LCS.MIT.EDU].878393.860409.JAR>
Date: Mon, 7 Apr 86 00:26:03 est
From: Kent Dybvig <dyb%indiana.csnet at CSNET-RELAY.ARPA>
I favor saying that "one possible" definition of LETREC is the
one given earlier, or even the following:
(letrec ((x v) ...) e ...)
=>
(let ((x 'any) ...)
(set! x v) ...
e ...)
Neither definition catches all the possible errors, but we have
already said that not all errors need be caught.
This isn't what I was after; I wanted a defining transformation, one
which would work in both directions and explain the error conditions
accurately. But it looks like this is infeasible, so I'll continue with
the current kludge, and give LETREC second-class status as syntactic
sugar (since it isn't really sugar, but has residual primitiveness), and
unassigned locations second-class status as errors (since one can't get
ahold of this useful error in its own right, but only as a by-product of
a LETREC).
Kludge of the day: one could define MIT Scheme's (LET ((var)) body)
uninitialized variable feature pretty easily in terms of LETREC:
(let ((var1) (var2) ...) body...)
==> (letrec ((var1 #f) (var2 #f) (value (begin body...))) value)
[where value isn't free in body...]. So LETREC actually is equipotent
with uninitialized bound variables.
Jonathan
∂09-Apr-86 0113 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA meaning of *global* define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 9 Apr 86 01:12:51 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 9 Apr 86 04:14:49 EST
Received: from ti-csl by csnet-relay.csnet id ag00237; 9 Apr 86 4:07 EST
Received: by tilde id AA09908; Tue, 8 Apr 86 18:05:19 cst
Date: Tue 8 Apr 86 17:58:36-CST
From: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: meaning of *global* define
To: RRRS-Authors%mit-mc@CSNET-RELAY.ARPA
Cc: Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
Message-Id: <12197297922.47.BARTLEY@CSC60>
I have a question for the MIT Scheme contingent that bears somewhat on
the discussion of DEFINE for the R↑3RS standard:
Suppose you have a Scheme implementation in which top-level forms are
evaluated in a `global' environment consisting of two (or more) nested
`frames'. Let's call the inner global frame USER and the outer global
frame SYSTEM. Thus, top-level expressions see all bindings in USER
plus all bindings in SYSTEM that are not shadowed in USER.
Suppose further that some identifier (say WRITE) is bound in SYSTEM
and not shadowed by a binding in USER and we evaluate the following
top-level expressions in order:
(define foo (lambda (x) (write x)))
(foo 3)
(define write (lambda (y) (newline)(display y)))
(foo 3)
It is my understanding that (in MIT Scheme) the two calls to FOO will
have different results because they see different WRITEs.
My concern here is not that the third form `redefines' WRITE, but that
it does so by causing FOO to see a different binding rather than a
different value in the same binding! That is, the third form
*inserts* a new binding of WRITE in USER, shadowing the binding in
SYSTEM. (I am assuming that this is the correct action for the third
form according to MIT Scheme.)
Is this strange behavior considered part of the expected semantics or
is the second DEFINE considered `an error' because it changes the
meaning of FOO? Would an implementation be considered faithful to
S&ICP and MIT Scheme if FOO ignored the new binding after once being
executed using the old binding?
Going beyond the current semantics of MIT Scheme, what would we really
want to happen here? Would anyone argue that an implementation must
allow that a new binding may be inserted between one execution of a
function and another, thus changing the L-value of one of its global
variables? My opinion is that this is questionable functionality.
Regards,
David Bartley
-------
∂09-Apr-86 0627 @MC.LCS.MIT.EDU:JMILLER@OZ.AI.MIT.EDU Re: meaning of *global* define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 9 Apr 86 06:26:26 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 9 APR 86 09:28:18 EST
Date: 9 Apr 1986 08:34-EST
Sender: JMILLER@MIT-OZ
Subject: Re: meaning of *global* define
From: JMILLER@MIT-OZ
Reply-To: JMiller%OZ@MC
To: RRRS-Authors@MC
Message-ID: <[MIT-OZ] 9-Apr-86 08:34:51.JMILLER>
In-Reply-To: <12197297922.47.BARTLEY@CSC60>
Absolutely correct. It is certainly my intention and desire that
the new binding be seen precisely as you would expect if your
model of Scheme was precisely the environment model shown in
S&ICP, defines DO side-effect environments, lookup IS deep search
at all times. It is NOT an error to do what you suggest -- it is
one of the most important features of the language since it is
PRECISELY what supports (my own, at least) interactive use of the
read eval print loop. If you change this one, in my opinion, you
reduce Scheme to the same utility as most compiler-based
languages, thus removing one of its most important features!
--Jim _
∂09-Apr-86 0820 @MC.LCS.MIT.EDU:GJS%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Re: meaning of *global* define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 9 Apr 86 08:20:02 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 9 APR 86 11:12:25 EST
Date: Wed 9 Apr 86 10:58:58-EST
From: "Gerald Jay Sussman" <GJS%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
Subject: Re: meaning of *global* define
To: Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
cc: rrrs-authors@MC.LCS.MIT.EDU
In-Reply-To: <12197297922.47.BARTLEY@CSC60>
Message-ID: <12197472751.27.GJS@OZ.AI.MIT.EDU>
You observed that the sequence of top-level forms:
(define foo (lambda (x) (write x)))
(foo 3)
(define write (lambda (y) (newline) (display y)))
(foo 3)
Had the effect that the second (FOO 3) used the new WRITE rather than
the old one.
Yes David, this is exactly what we wanted for our system! Thank you
for clearly pointing out the consequences to those of us who did not
deduce all of them so clearly.
Top-level DEFINE is an edge case where interactive, incremental
programming and debugging are in conflict with the goals of a clean,
static meaning for a program. This conflict is unavoidable --
completely static meanings for program text does not make sense in an
interactive, incremental environment.
The reason why it is important to allow one to insert that binding is
that it allows us to construct an independent USER environment that
can shadow the SYSTEM environment, and as you observe, to
incrementally add to the USER environment. Thus, we can allow a
student to redefine CAR (perhaps to try out Church's idea for data --
Exercise 2.3, p.84 of S&ICP) without killing the system. In fact, in
our system one can safely redefine any system procedure, because the
change is only visible to the user. Thus, top-level definitions are
to be thought of as mutating a "local directory node" in a "file
system".
In particular, you say:
"Is this strange behavior considered part of the expected semantics or
is the second DEFINE considered `an error' because it changes the
meaning of FOO? Would an implementation be considered faithful to
S&ICP and MIT Scheme if FOO ignored the new binding after once being
executed using the old binding?"
Somehow I don't quite see the significance of the time reference: "...
after once being executed" in a discussion of semantics. Presumably
you are worried about the difficulty of implementing this behavior in
an efficient manner. I sympathize. CPH can explain our strategy
here. On the other hand, it does allow a user to program effectively
without knowing the contents of the manual. He only has to know a
handful of special form names to avoid in his programs. Indeed, it
allows several people working together to only agree on the interface
names and not to worry about the names they use within their program
segments.
-------
∂09-Apr-86 1026 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@mc.lcs.mit.edu meaning of *global* define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 9 Apr 86 10:24:31 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 9 Apr 86 13:26:14 EST
Received: from mc.lcs.mit.edu by CSNET-RELAY.ARPA id a002244; 9 Apr 86 13:19 EST
Date: 9 Apr 1986 11:24 EST (Wed)
Message-ID: <JINX.12197477372.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@xx.lcs.mit.edu>
To: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Cc: RRRS-Authors%mit-mc@CSNET-RELAY.ARPA
Subject: meaning of *global* define
In-reply-to: Msg of 8 Apr 1986 18:58-EST from David Bartley <Bartley%ti-csl.csnet at CSNET-RELAY.ARPA>
Is this strange behavior considered part of the expected semantics or
is the second DEFINE considered `an error' because it changes the
meaning of FOO? Would an implementation be considered faithful to
S&ICP and MIT Scheme if FOO ignored the new binding after once being
executed using the old binding?
This is the expected semantics of incremental DEFINE. An
implementation would not be faithful to MIT Scheme (and S&ICP , see
page 413, section 5.1.5, although in this case the incompatibility
would be minor) if the second possibility were used.
Going beyond the current semantics of MIT Scheme, what would we really
want to happen here? Would anyone argue that an implementation must
allow that a new binding may be inserted between one execution of a
function and another, thus changing the L-value of one of its global
variables? My opinion is that this is questionable functionality.
I disagree. Incremental DEFINE is extremely useful when debugging.
In its absence, a lot of code can only be fixed by "re-loading", but
this option is unavailable when the code is non-deterministic and/or
has built a large state which takes very long to regenerate.
Incremental DEFINE (as opposed to internal DEFINE, they are quite
different beasts) is a means to patch a piece of code, its static
use is discouraged. It is only useful (necessary ?) in the presence
of a (common) class of bugs, not to write a program from scratch. It
is what some T people would call a feature of the "programming
environment", and not the language.
One of the features of Lisp (or rather, the surrounding programming
environments) which I have always liked was that many errors were
"patchable" and "proceedable". This is (to me) an essential feature of
interactivness which traditional compiler based languages (or their
programming environments) lack.
It is unfortunate that some features useful (needed) for incremental
development and debugging are not semantically "clean", but nobody (to
my knowledge) requires cleanliness from steppers and tracing
facilities, so it seems inconsistent to require cleanliness from yet
another debugging tool.
∂09-Apr-86 1250 @MC.LCS.MIT.EDU:cth%indiana.csnet@.ARPA delayed replies
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 9 Apr 86 12:50:10 PST
Received: from .ARPA by MC.LCS.MIT.EDU 9 Apr 86 15:51:52 EST
Received: from indiana by csnet-relay.csnet id aa03957; 9 Apr 86 15:37 EST
Date: Wed, 9 Apr 86 13:39:53 est
From: Chris Haynes <cth%indiana.csnet@.ARPA>
To: rrrs-authors@mc.lcs.mit.edu
Subject: delayed replies
Dan and I were mistakenly sending notes only to the local notesfile,
so here's some belated responses.
/**** iuvax:scheme-rrrs / iuvax!cth / 4:05 pm Mar 18, 1986 ****/
I'm pretty comfortable with Jonathan's recommendations of 3/14.
As far as I know, coalescing of procedures that behave identically
and always will (given any possible side affects) does not
significantly disrupt object-oriented programming. If anyone has a
practical example to the contrary, I'd like to see it. Coalescing
does introduce a technicality which could conceivably cause
confusion, but so far I'm more convinced by the efficiency concerns.
Lambda-lifting is very valuable. (I agree with Dave that programmers
shouldn't be expected to perform such optimizations themselves. We
once encouraged manual lambda-lifting here, but I've been arguing for
the last year that one shouldn't have to play compiler at the expense
of program clarity.)
Splitting is harder. It causes real problems for object-oriented
programming, but beta-conversion can also be very important. Thus I
think two forms of lambda are justified. LAMBDA ought to produce
non-splitting procedures, but a splitting form would be valuable and
we would do well to include it (optionally) in the RRRS. A good
syntactic extension mechanism would allow one to redefine LAMBDA to
be the splitting form if that was acceptible for a given program. It
wouldn't even take much to convince me that primitive procedures
should be of the splittable kind, so (EQ? + +) might be false. (Will
once noted this as bug in MacScheme.)
As long as EQ? is usable on procedures (as above), I don't see why
EQV? couldn't be prohibited on procedures. This would make an
implementation-indendent EQV? possible, which would be desirable.
(EQUAL? should then use EQ? on procedures and EQV? on other atoms,
which would require the PROCEDURE? predicate. Hmmm...)
/* ---------- */
/**** iuvax:scheme-rrrs / iuvax!dfried / 1:43 pm Mar 29, 1986 ****/
I just wanted to second Bert's comments about confusion caused by
define "doing a rec".
Dan
/* ---------- */
/**** iuvax:scheme-rrrs / iuvax!dfried / 8:26 am Apr 2, 1986 ****/
I object to any mutilation of "letrec" and its simpler sibling "rec".
BTW (rec a (cons 3 a)) could be a cons cell whose "cdr" points to itself.
Dan
/* ---------- */
∂09-Apr-86 1320 @MC.LCS.MIT.EDU:cth%indiana.csnet@.ARPA Use at Indiana University
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 9 Apr 86 13:20:21 PST
Received: from .ARPA by MC.LCS.MIT.EDU 9 Apr 86 15:52:15 EST
Received: from indiana by csnet-relay.csnet id ab03957; 9 Apr 86 15:38 EST
Date: Wed, 9 Apr 86 13:40:53 est
From: Chris Haynes <cth%indiana.csnet@.ARPA>
To: scheme@mc.lcs.mit.edu
Subject: Use at Indiana University
/**** iuvax:scheme-list / iuvax!cth / 12:59 am Mar 31, 1986 ****/
Scheme is used in a broad range of teaching and research contexts throughout
the Indiana University Computer Science Department. The primary courses
which use Scheme are
-- Programming Languages (Junior/Senior level, with some graduate students)
Scheme is used throughout this course to express the semantics of
programming languages and their implementation. A sequence of interpreters
is developed which demonstrate a systematic approach to deriving
implementation from abstract semantics. The notes for this
unique course are turning into a book by Friedman, Wand, Haynes and
Kohlbecker.
-- Advanced Concepts in Programming Languages (graduate level)
In this course Dan Friedman uses Scheme is used to study a variety
of advanced PL features, such as concurrency and reflection.
Typical projects require students to implement in Scheme the essence
of various proposed language mechanisms, such as data flow or actors.
-- Operating Systems I and II (senior and graduate level)
As I teach this course (others here do it a bit differently) after a few
weeks of interrupt handler programming in assembly language, the remaining
course projects are done in Scheme. (I wish we had direct access to
hardware interrupts and I/O controllers in a Scheme system. Some day...)
This year I gave the students a process scheduler written in Scheme using
engines, and asked them to add semaphores and monitors. The second
semester project is to implement all of the Ada concurrency mechanisms that
seem to make sense in a Scheme environment (including termination and
delays).
-- Compiler Construction I and II (senior and graduate level)
is often taught with extensive use of Scheme, including lexical analysis,
parsing and code generation. This semester Kent Dybvig's class is
writing an optimizing compiler for a subset of C in Scheme.
-- Denotational Semantics (advanced graduate level)
is taught using a Semantic Prototyping System developed by Mitch
Wand that assists in the translation of denotational semantics into
running Scheme programs. (This system includes an ML-style type checker.)
In most other advanced courses students are free to use any language of their
choosing, and many choose Scheme, particularly in the AI courses. Scheme is
also used in a variety of student projects, some of them outside of the
department. Examples include (1) an oil exploration model for geology
instruction that is being tied into an expert system, and uses engines for
time-shared simulation, (2) a Scheme Development System, inspired by Knuth's
WEB, which targets Scheme and line printers instead of Pascal and Tex, and
(3) a Scheme Implementation of Neural Networks (SINN).
In the fall, George Springer will teach an honors introduction to programming
course using Scheme, The Little LISPer, and parts of the Abelson and Sussman
text. We anticipate expanding the use of Scheme in future introductory
courses. Scheme is also used in a variety of research projects, including
the study of programming language sequential control, logic programming, data
typing, concurrency, compilers, syntactic extension mechanisms, and hardware
design methodology.
/* ---------- */
∂09-Apr-86 1759 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: Where'd all that mail come from??!!
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 9 Apr 86 17:59:28 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 9 Apr 86 20:59:18 EST
Received: from ti-csl by csnet-relay.csnet id aa07435; 9 Apr 86 20:53 EST
Received: by tilde id AA12325; Wed, 9 Apr 86 19:10:13 cst
Date: Wed 9 Apr 86 18:59:28-CST
From: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Re: Where'd all that mail come from??!!
To: JINX%OZ.AI.MIT.EDU%xx.lcs.mit.edu@CSNET-RELAY.ARPA
Cc: RRRS-Authors%MIT-MC@CSNET-RELAY.ARPA,
Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
In-Reply-To: <JINX.12197319606.BABYL@MIT-OZ>
Message-Id: <12197571147.41.BARTLEY@CSC60>
Two comments:
(1)
>From: Bill Rozas <JINX%OZ.AI.MIT.EDU%xx.lcs.mit.edu@csnet-relay>
>
> -- On embedded DEFINEs: I agree with CPH that these should be
> considered fossils preserved in the standard for the benefit of
> readers of S&ICP. They should be understood as a stylistic
> alternative to LETREC and thus defined in terms of NAMED-LAMBDA (or
> its equivalent). JAR seems to have struck the right balance in his
> suggested consensus.
>
>I disagree that DEFINE is a fossil. ...
Sorry--I was so taken with the idea that CPH would use such
terminology that I had to quote him! My point is that we should
freeze, not improve on, the meaning of local defines.
(2) JAR has privately persuaded me that #T and #F are less insidious
than I first took them to be. I'd characterize my initial reaction as
"Why bother with a trivial, clearly incompatible change?" JAR argues
convincingly that the change is reasonably limited in repercussions
and is aesthetically worth the cost. I agree.
Regards,
David Bartley
-------
∂10-Apr-86 0554 @MC.LCS.MIT.EDU:adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA LET from LET* ?
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 10 Apr 86 05:47:38 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 10 Apr 86 08:49:32 EST
Received: from tektronix by csnet-relay.csnet id ad13403; 10 Apr 86 8:46 EST
Received: by tektronix (5.31/5.14)
id AA07318; Wed, 9 Apr 86 09:27:57 PST
Received: by tekchips (5.31/5.14)
id AA18957; Wed, 9 Apr 86 09:28:30 PST
Message-Id: <8604091728.AA18957@tekchips>
To: dyb%indiana.csnet@CSNET-RELAY.ARPA
Cc: rrrs-authors@mc.lcs.mit.edu
Subject: LET from LET* ?
Date: 09 Apr 86 09:28:28 PST (Wed)
From: adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
I think that LET from LET* is easy, though certainly not as easy as
the other way around:
(let ((x v) ...) e ...)
=>
(let* ((y v) ...) ; y not appearing in subsequent v or e
(let* ((x y) ...) e ...))
(This definition is not so silly as it might seem, since it offers
a straightforward sequential implementation of LET.)
I don't think Gerry's point was that it is hard to implement LET using only
LET* (or any sequential operators), but that it is hard to specify exactly
what LET specifies (and doesn't specify) using only LET*. As you say, what
you give is a legitimate implementation. But, it is not an equivalent
specification, because it dictates an order where the LET did not.
-Norman
∂10-Apr-86 0554 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA arg lists to APPLY
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 10 Apr 86 05:54:42 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 10 Apr 86 08:55:46 EST
Received: from tektronix by csnet-relay.csnet id ae13403; 10 Apr 86 8:46 EST
Received: by tektronix (5.31/5.14)
id AA09072; Wed, 9 Apr 86 10:31:49 PST
Received: by tekchips (5.31/5.14)
id AA19944; Wed, 9 Apr 86 10:32:21 PST
Message-Id: <8604091832.AA19944@tekchips>
To: scheme%mit-mc%tektronix.csnet@CSNET-RELAY.ARPA
Subject: arg lists to APPLY
Date: 09 Apr 86 10:32:19 PST (Wed)
From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
I haven't checked the manuals for T or Scheme but it was certainly the
intent that the list passed to APPLY is unrelated to the list that a
rest-parameter gets bound to. The rest-list should always be freshly
consed, so e.g. the procedure LIST is equivalent to (LAMBDA X X). The
last argument to APPLY must be a proper list. I think Common Lisp
takes the same stance.
This question came up recently on the Common-Lisp mailing list. The
unofficial consensus, as I understood it, was that the book is vague on
this point and requires correcting; that the last argument to APPLY
should be a proper list; and that a list passed as an argument to APPLY
might or might not share list structure with an eventual &REST argument
resulting from the application.
Until this discussion I had never heard anyone suggest that it was ok for
an implementation of Scheme to allow the list passed to APPLY to share
structure with the list that a rest-argument gets bound to.
For what it's worth, two formal semantics for Scheme have been published
(1980 and 1984) and a third is expected to be published soon. The first
two define the domain of procedures as F = E* --> K --> C, and the third
defines F = L x (E* --> K --> C). The sharing mentioned above is
inconceivable with either definition, and the changes that would be
required to allow such sharing are pretty gross.
In my opinion, therefore, Scheme and Common Lisp diverge on this as on
many other issues.
It should not be very difficult for a compiler to arrange things so that
rest arguments that are merely passed on as argument lists to APPLY never
get consed. Whether this is important enough to worry about is another
matter entirely.
Peace, Will
∂10-Apr-86 0836 @MC.LCS.MIT.EDU:gls@aquinas.think.com Where'd all that mail come from??!!
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 10 Apr 86 08:36:23 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 10 Apr 86 11:38:20 EST
Received: from godot.think.com by CSNET-RELAY.ARPA id a015079;
10 Apr 86 11:24 EST
Received: from thorlac by GODOT.THINK.COM via CHAOS; Thu, 10 Apr 86 11:23:28 est
Date: Thu, 10 Apr 86 11:25 EST
From: Guy Steele <gls@aquinas.think.com>
Subject: Where'd all that mail come from??!!
To: Bartley%ti-csl.csnet@CSNET-RELAY.ARPA,
RRRS-Authors%MIT-MC@CSNET-RELAY.ARPA
Cc: gls@aquinas.think.com
In-Reply-To: <12197283428.47.BARTLEY@CSC60>
Message-Id: <860410112505.4.GLS@THINK-THORLAC.ARPA>
Date: Tue 8 Apr 86 16:38:59-CST
From: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
... I would counter by
arguing that the very attempt to standardize Scheme, which is
motivated by the present and pending existence of several
implementations, marks the transition from `experimental' language to
`production' language for many of us. As I've heard GJS remark, maybe
it's time to invent yet another language for all these new ideas and
let Scheme remain what it is!
Regards,
David Bartley
-------
Indeed. It is too late for SCHEME to become more beautiful.
Like Common Lisp, it has become too important to too many people,
and has therefore become subject to design by committee.
Beautiful languages are designed by taking a collection of good
ideas and then carefully throwing things away rather than by adding
new things. This happened some to Common Lisp in the early stages.
Once a language becomes important, it's too hard to throw things
away; you can only add things.
Maybe it is time to invent a new language. (I recommend to
everyone to study Milner's proposal for standard ML in the
proceedings of the 1984 Lisp Conference. I thought that an amazing
amount of expressive power was achieved with great economy of
features and concepts.)
--Guy
∂10-Apr-86 1047 JAR@MC.LCS.MIT.EDU Where'd all that mail come from??!!
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 10 Apr 86 10:44:48 PST
Date: Thu, 10 Apr 86 13:46:35 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: Where'd all that mail come from??!!
To: gls@AQUINAS.THINK.COM
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU,
Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
In-reply-to: Msg of Thu 10 Apr 86 11:25 EST from Guy Steele <gls at aquinas.think.com>
Message-ID: <[MC.LCS.MIT.EDU].880265.860410.JAR>
Date: Thu, 10 Apr 86 11:25 EST
From: Guy Steele <gls at aquinas.think.com>
... It is too late for SCHEME to become more beautiful.
Like Common Lisp, it has become too important to too many people,
and has therefore become subject to design by committee.
Beautiful languages are designed by taking a collection of good
ideas and then carefully throwing things away rather than by adding
new things. This happened some to Common Lisp in the early stages.
Once a language becomes important, it's too hard to throw things
away; you can only add things.
I agree with this. I don't want people thinking that I'm trying to make
lots of changes to the language to try to make it perfect. At this
point I'm just trying to clarify a few things that don't matter very
much, tweak a few things to improve the consistency of the report, and
to make it easy for existing implementations to be comptible with the
report (the last category motivated my bringing up the questions of
immutable structure and procedure coalescing/splitting). I think I'm
practically done with this process, at least as far as changes go, if
not additions, which as you say are less problematic.
My attempt to change eqv? and eq? may have been misguided. My rewrite
of that section doesn't basically change anything, but presents a
compromise which I think everyone will be more or less satisfied with.
Some of my other crusades have probably also been too ambitious, and
I'll try to give up such efforts as of today.
BUT... I ask for an exception in the case of #t and #f. This is the
last major incompatible change I'll ask for. In consideration for
compatibility, however, I propose leaving in #!true and #!false (and
maybe even #!null), but as non-essential features, so they can be phased
out as people's consciences permit.
Maybe it is time to invent a new language....
Clearly. I have been saying this for at least 3 years, maybe longer.
Working on it.
Jonathan
∂10-Apr-86 1628 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA CS5PA Summer Session
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 10 Apr 86 16:27:54 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 10 Apr 86 19:29:23 EST
Received: from ti-csl by csnet-relay.csnet id a019988; 10 Apr 86 19:18 EST
Received: by tilde id AA12490; Thu, 10 Apr 86 17:45:20 cst
Date: Thu, 10 Apr 86 17:45:20 cst
From: John Chen <jchen%tilde%ti-csl.csnet@CSNET-RELAY.ARPA>
To: mantak%ucsb.csnet@CSNET-RELAY.ARPA
Subject: CS5PA Summer Session
Prof. Shing:
I forgot to tell you that the stuff I had for 5pa last summer (such as HW
assignments, quizes, and final) were kept in my directory (~chen) of csil.
If you are interested and that directory is still alive, then the stuff
is under subdirectory "./5pa".
Another thought I have after last summer was the TA office hours. I worked
as a summer TA a few years ago (Kem Chow was the other TA) and you taught
that summer, too. There were TA hours 10-12 and 2-4 every Tu W Th. Each
TA took 6 hours per week. With discussion section on Monday and instructors'
office hours on Friday, every weekday was well covered for the kids to ask
questions.
John Chen
∂11-Apr-86 0719 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA early binding
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 11 Apr 86 07:18:37 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 11 Apr 86 10:20:24 EST
Received: from ti-csl by csnet-relay.csnet id ab27067; 11 Apr 86 9:51 EST
Received: by tilde id AA28648; Fri, 11 Apr 86 08:40:19 cst
Date: Fri 11 Apr 86 08:36:58-CST
From: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: early binding
To: RRRS-Authors%mit-mc@CSNET-RELAY.ARPA
Cc: Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
Message-Id: <12197982112.51.BARTLEY@CSC60>
{I'm resending this because the mailer seems to have lost the previous
attempt and substituted a random message from a "jchen".}
I have yet another question for the MIT contingent which appears to
relate to issues of interest to the rest of RRRS-authors...
(Incidentally, these questions are merely attempts to understand the
MIT position, not poorly disguised attempts to undermine it! I
expected you to jump all over my previous question (and I wasn't
disappointed). But I had to know. I also agree with you (now).)
What meaning should we give to user declarations like MIT Scheme's
`usual-integrations' and PC Scheme's `pcs-integrate-primitives'? I
think most (many? (some? (I?))) would agree that it includes the
notion that the compiler is free to early-bind the specified entities
even if those entities happen to be rebound or reassigned at a later
time. Does it also mean that the compiler may early-bind such
entities if they have been rebound or reassigned *previously*?
Consider the following top-level expressions evaluated in order:
(declare things-like-car-and-cdr-may-be-integrated)
(define car ...)
(define foo (lambda (x)(+ (car x)(cdr x))))
(define cdr ...)
(foo '(2 . 2))
May the compiler integrate both car and cdr in the definition of foo,
only cdr, or neither? If it integrates car, is it with the standard
definition or the new one? What happens now in your favorite
implementation? What do you want to happen?
I think this is of general interest because it has been suggested that
we introduce various compiler directives to get around differences of
opinion expressed on this mailing list. Is it possible we can all
agree on a general policy for how such early-binding declarations
should operate?
Regards,
David Bartley
-------
∂11-Apr-86 1054 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@mc.lcs.mit.edu early binding
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 11 Apr 86 10:54:35 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 11 Apr 86 12:54:26 EST
Received: from mc.lcs.mit.edu by CSNET-RELAY.ARPA id a028818;
11 Apr 86 12:32 EST
Date: 11 Apr 1986 10:48 EST (Fri)
Message-ID: <JINX.12197995178.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@xx.lcs.mit.edu>
To: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Cc: RRRS-Authors%mit-mc@CSNET-RELAY.ARPA
Subject: early binding
In-reply-to: Msg of 11 Apr 1986 09:36-EST from David Bartley <Bartley%ti-csl.csnet at CSNET-RELAY.ARPA>
I, and most (all ?) of us believe that in the following code
(declare things-like-car-and-cdr-may-be-integrated)
(define car ...)
(define foo (lambda (x)(+ (car x)(cdr x))))
(define cdr ...)
(foo '(2 . 2))
cdr should be integrated with its usual meaning, but if car is
integrated, it should be integrated with the new definition.
This is the behaviour in Gator Scheme. CScheme, which has an older
"syntaxer" behaves differently, but its behaviour is considered a bug
by most of us.
Ideally, integrated code contains some integration information which
can be checked at load time. If the integration assumptions are not
inconsistent with the system where the code is loaded, there is
nothing to be done. Otherwise an error or "re-compilation" are
approrpriate.
∂11-Apr-86 1459 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@mc.lcs.mit.edu early binding
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 11 Apr 86 14:29:06 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 11 Apr 86 17:30:41 EST
Received: from mc.lcs.mit.edu by CSNET-RELAY.ARPA id a001554;
11 Apr 86 17:22 EST
Date: Fri, 11 Apr 1986 17:22 EST
Message-ID: <CPH.12198066774.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@xx.lcs.mit.edu
To: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Cc: RRRS-Authors%mit-mc@CSNET-RELAY.ARPA
Subject: early binding
In-reply-to: Msg of 11 Apr 1986 09:36-EST from David Bartley <Bartley%ti-csl.csnet at CSNET-RELAY.ARPA>
Actually, the following code
(declare things-like-car-and-cdr-may-be-integrated)
(define car ...)
(define foo (lambda (x)(+ (car x)(cdr x))))
(define cdr ...)
(foo '(2 . 2))
in MIT Scheme will not cause either CAR or CDR to be integrated
anywhere within the block in which the declaration appears (contrary
to Bill's previous statement).
Declarations of this sort mean that "all of the free references to
these variables that occur within this block may be integrated".
Because CAR and CDR are not free within the above code, they may not
be integrated.
The problem that I expect to cause confusion is (as usual) the
sequentiality of DEFINE. This would imply that only CAR was bound
when the definition of FOO was compiled. There are two issues here:
1. Declarations are totally ignored when typed into the
read-eval-print loop. This is true simply because the syntax and
compilation programs that notice declarations are not run on code
that is typed in. It is also unclear to me that declarations are
useful when typing code in like this.
2. When compiling files, top-level DEFINE is treated almost
exactly like internal DEFINE. That is, the file is scanned to
extract all the top-level definitions. Most of the code analysis
treats these top-level definitions as if they were a kind of "open
LETREC", that is, a partial specification of an environment
frame's bindings.
In particular, the analysis for integration declarations looks at
the entire set of definitions as if they were simultaneously
bound, and ignores the sequentiality information.
The combination of these two facts results in what I consider a
desirable behavior: declarations need not worry about incremental
definitions.
The reason that this is desirable is that declarations are intended to
inform the compiler about a program's static structure -- to help it
produce efficient code when it is unable to prove through analysis
that the desired transformations can be made. Incremental
definitions, on the other hand, should never be used in writing a
program -- they are are a dynamic mechanism which has nothing to do
with a program's static structure.
∂11-Apr-86 1554 @MC.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: meaning of *global* define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 11 Apr 86 15:54:35 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 11 Apr 86 18:56:27 EST
Received: from tektronix by csnet-relay.csnet id ag02130; 11 Apr 86 18:44 EST
Received: by tektronix (5.31/5.14)
id AA18567; Fri, 11 Apr 86 12:08:39 PST
Received: by tekchips (5.31/5.14)
id AA16812; Fri, 11 Apr 86 12:09:17 PST
Message-Id: <8604112009.AA16812@tekchips>
To: rrrs-authors%mit-mc%tektronix.csnet@CSNET-RELAY.ARPA
Subject: Re: meaning of *global* define
Date: 11 Apr 86 12:09:15 PST (Fri)
From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
There seems to be widespread agreement on the following three points:
1. a. Users should be able to use whatever names they like without
worrying about conflicts.
b. A programming environment should support debugging through some
kind of incremental definition facility.
2. MIT's peculiar semantics for DEFINE is a mechanism that can be used
to satisfy both 1.a and 1.b.
3. MIT's peculiar semantics for DEFINE is (semantically) dirty.
It doesn't follow that any mechanism satisfying both 1.a and 1.b must be
semantically dirty.
There exist semantically clean mechanisms that take care of 1.a alone
(e.g. first class environments WITHOUT side effects), and I agree with
JINX that 1.b is an issue for the programming environment rather than
the language per se. What I don't understand (but would like to) is
why MIT's semantics for DEFINE is more useful for debugging than
semantically clean mechanism such as assignments and first class
environments (without side effects).
In David Bartley's example, it seems obvious that the USER environment
should be disjoint from the SYSTEM environment in the sense that there
should be no identifier I such that USER(I) = SYSTEM(I). (This can be
accomplished without any hocus pocus like side effects to environments
or MIT semantics for DEFINE.) Then an assignment to CAR or WRITE or FOO
won't kill the system because the system isn't using the binding of CAR
or WRITE or FOO that was stored into.
I apologize for the fact that MacScheme doesn't do this right. It has
more to do with a shortage of RAM than with semantics.
Peace, Will
∂11-Apr-86 1722 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@mc.lcs.mit.edu early binding
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 11 Apr 86 17:22:22 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 11 Apr 86 20:24:19 EST
Received: from mc.lcs.mit.edu by CSNET-RELAY.ARPA id a002940;
11 Apr 86 20:16 EST
Date: 11 Apr 1986 20:16 EST (Fri)
Message-ID: <JINX.12198098605.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@xx.lcs.mit.edu>
To: CPH%OZ.AI.MIT.EDU@xx.lcs.mit.edu
Cc: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>,
RRRS-Authors%mit-mc@CSNET-RELAY.ARPA
Subject: early binding
In-reply-to: Msg of 11 Apr 1986 17:22-EST from CPH%OZ.AI.MIT.EDU at xx.lcs.mit.edu
I was careless. I did not notice
(define cdr ...)
in
(declare things-like-car-and-cdr-may-be-integrated)
(define car ...)
(define foo (lambda (x)(+ (car x)(cdr x))))
(define cdr ...)
(foo '(2 . 2))
That's why I said that cdr would be integrated but not car.
∂11-Apr-86 1726 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: early binding
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 11 Apr 86 17:25:46 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 11 Apr 86 20:26:39 EST
Received: from ti-csl by csnet-relay.csnet id ac02950; 11 Apr 86 20:19 EST
Received: by tilde id AA18223; Fri, 11 Apr 86 18:50:29 cst
Date: Fri 11 Apr 86 18:44:19-CST
From: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Re: early binding
To: CPH%OZ.AI.MIT.EDU%xx.lcs.mit.edu@CSNET-RELAY.ARPA
Cc: RRRS-Authors%mit-mc@CSNET-RELAY.ARPA,
Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
In-Reply-To: <CPH.12198066774.BABYL@MIT-OZ>
Message-Id: <12198092677.51.BARTLEY@CSC60>
I'd like to follow up on CPH's reply:
> 1. Declarations are totally ignored when typed into the
> read-eval-print loop. This is true simply because the syntax and
> compilation programs that notice declarations are not run on code
> that is typed in. It is also unclear to me that declarations are
> useful when typing code in like this.
It appears that MIT Scheme never performs integrations on top-level
expressions entered from the keyboard. I guess my only objection to
that is that the casual user who sits down at your machine to type in
his favorite benchmark is fooled into thinking your implementation is
slower than it really is. That can be seriously unfair to both a
commercial implementer and his potential customer! But, ignoring
nasty profit motives...
Perhaps it would be useful to let INTEGRATE-MUMBLE flags take on three
values: `don't', `don't for keyboard input', and `do'. The (greedy)
implementer would default to `do' when exhibiting to prospective
customers worried about comparative ``benchmarketing'' [sic] while the
typical user might change it to `don't for keyboard input'.
What does MIT Scheme do for expressions evaluated out of editor
buffers? Are they treated like inputs from files or inputs from the
keyboard?
> 2. When compiling files, top-level DEFINE is treated almost
> exactly like internal DEFINE. That is, the file is scanned to
> extract all the top-level definitions. Most of the code analysis
> treats these top-level definitions as if they were a kind of "open
> LETREC", that is, a partial specification of an environment
> frame's bindings.
>
> In particular, the analysis for integration declarations looks at
> the entire set of definitions as if they were simultaneously
> bound, and ignores the sequentiality information.
>
>The combination of these two facts results in what I consider a
>desirable behavior: declarations need not worry about incremental
>definitions.
What do you mean by ``a kind of "open LETREC", that is, a partial
specification of an environment frame's bindings''? Earlier you say:
"Declarations of this sort mean that "all of the free references to
these variables that occur within this block may be integrated".
Because CAR and CDR are not free within the above code, they may not
be integrated."
The idea seems to be that it is ``open'' in the sense that top-level
DEFINEs create bindings in the existing environment, not a new
extension (as a real LETREC would create), but it is like a LETREC
because the top-level bindings are assumed to occur simultaneously.
It is also like a LETREC in that it defines a boundary for specifying
whether a reference to CAR or CDR is ``free'' or not. This is what
confuses me---is it a binding level or isn't it? If so, perhaps the
idea is that it IS a LETREC but all top-level bindings are also
exported to the enclosing (global) environment. (I don't think that's
what you mean.)
Is this ``open LETREC'' subject to further extension? What happens if
I have a (LOAD "FILE2") inside FILE1? Is it a nested ``open LETREC''
or is it merged into FILE1's? Can I assume that if a top-level DEFINE
of FOO in FILE1 is the only place in FILE1 that affects the value of
FOO, that FOO is constant and thus integrable? Or can I use such info
only to inhibit integrations?
Suppose I type (BEGIN (LOAD "FILE1")(LOAD "FILE2")), or type the two
loads sequentially, at top level. What interactions, if any, are
there between the ``open LETRECs'' of the two files? I assume that a
DEFINE of CAR in FILE2 will not inhibit integration of CAR in FILE1
but a DEFINE of CAR in FILE1 will inhibit integration of CAR in FILE2.
I'm very uneasy at the idea that a file has much of the status of a
single expression, like LETREC, particularly if I can't formulate what
it means any better than this (can you?). Perhaps it is workable,
though. I'd like to know what others think and what their experience
has been.
Regards,
David Bartley
-------
∂11-Apr-86 1826 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@mc.lcs.mit.edu early binding (150 lines)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 11 Apr 86 18:26:01 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 11 Apr 86 21:23:46 EST
Received: from mc.lcs.mit.edu by CSNET-RELAY.ARPA id a003441;
11 Apr 86 21:20 EST
Date: Fri, 11 Apr 1986 21:21 EST
Message-ID: <CPH.12198110290.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@xx.lcs.mit.edu
To: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Cc: RRRS-Authors%mit-mc@CSNET-RELAY.ARPA
Subject: early binding (150 lines)
In-reply-to: Msg of 11 Apr 1986 19:44-EST from David Bartley <Bartley%ti-csl.csnet at CSNET-RELAY.ARPA>
Date: Friday, 11 April 1986 19:44-EST
From: David Bartley <Bartley%ti-csl.csnet at CSNET-RELAY.ARPA>
> 1. Declarations are totally ignored when typed into the
> read-eval-print loop. This is true simply because the syntax and
> compilation programs that notice declarations are not run on code
> that is typed in. It is also unclear to me that declarations are
> useful when typing code in like this.
It appears that MIT Scheme never performs integrations on top-level
expressions entered from the keyboard. I guess my only objection to
that is that the casual user who sits down at your machine to type in
his favorite benchmark is fooled into thinking your implementation is
slower than it really is.
Actually, I don't have any real objection to declarations working when
typed in -- it is just the case that they currently do not in MIT
Scheme. The model for declarations that I described in my earlier
message does not fit the "top level interaction" view very well, since
it is essentially a static model. But, appropriate or not, I think
that it would work fine if interactive declarations were implemented.
But, ignoring nasty profit motives...
Aside from "nasty profit motives", I can think of several very good
reasons why I would like people to think our implementation was fast!
Besides, I had no idea you were raking in "nasty profits". Are they
different from "nice profits"? Can I have some too?
What does MIT Scheme do for expressions evaluated out of editor
buffers? Are they treated like inputs from files or inputs from the
keyboard?
Actually, like keyboard inputs. This interface needs alot of work and
that is one of the things needed -- declarations have to be treated
specially in this case. In particular, suppose that you want to
compile a single procedure definition in a buffer that contains a top
level declaration in some other part of the buffer. It seems to me
that the editor should know about the declaration specially and use it
when compiling single procedures.
What do you mean by ``a kind of "open LETREC", that is, a partial
specification of an environment frame's bindings''?
The idea seems to be that it is ``open'' in the sense that top-level
DEFINEs create bindings in the existing environment, not a new
extension (as a real LETREC would create), but it is like a LETREC
because the top-level bindings are assumed to occur simultaneously.
It is also like a LETREC in that it defines a boundary for specifying
whether a reference to CAR or CDR is ``free'' or not. This is what
confuses me---is it a binding level or isn't it?
Sorry about this confusion. This is an idea which I have been using
for so long that I forgot how tricky it was in the first place.
This "open LETREC" does *not* create a new binding level. It is
mostly just a convenient way of collecting all of the definitions
together into one place. This is very useful when doing analysis of
code because you generally want to see all of the defined variables at
the same time.
The definitions are still thought of as happening to the environment
frame in which the expression is evaluated.
Is this ``open LETREC'' subject to further extension? What happens if
I have a (LOAD "FILE2") inside FILE1? Is it a nested ``open LETREC''
or is it merged into FILE1's? Can I assume that if a top-level DEFINE
of FOO in FILE1 is the only place in FILE1 that affects the value of
FOO, that FOO is constant and thus integrable? Or can I use such info
only to inhibit integrations?
Suppose I type (BEGIN (LOAD "FILE1")(LOAD "FILE2")), or type the two
loads sequentially, at top level. What interactions, if any, are
there between the ``open LETRECs'' of the two files? I assume that a
DEFINE of CAR in FILE2 will not inhibit integration of CAR in FILE1
but a DEFINE of CAR in FILE1 will inhibit integration of CAR in FILE2.
I'm very uneasy at the idea that a file has much of the status of a
single expression, like LETREC, particularly if I can't formulate what
it means any better than this (can you?).
The problem with all of these questions is that they assume a little
too much about the nature of this "open LETREC" concept. I should
have stressed, and will do so now: This is just a model used in the
code analyzer, with a few limited purposes. Open LETRECs are never,
ever evaluated. Those that appear at "top level" are converted back
into individual definitions once the code analyzer is done. The
others, i.e. the ones appearing because of local DEFINEs, disappear
because the variables they define become merged with the bindings of
the LAMBDA expression in which they appear. More on this below.
So to speak of an interaction between this concept and LOAD is fairly
meaningless -- by the time the LOAD is executed the analysis is
already complete and the open LETRECs are gone.
Now, if you were to substitute INCLUDE for LOAD in the above comments,
then they would be sensible -- and have fairly obvious answers.
Suppose I type (BEGIN (LOAD "FILE1")(LOAD "FILE2")), or type the two
loads sequentially, at top level. What interactions, if any, are
there between the ``open LETRECs'' of the two files? I assume that a
DEFINE of CAR in FILE2 will not inhibit integration of CAR in FILE1
but a DEFINE of CAR in FILE1 will inhibit integration of CAR in FILE2.
This is actually an important point. I'm not sure what the behavior
here should be. The problem is that declarations are "per file". The
current implementation in MIT Scheme uses the declarations at compile
time, and not at run time. So there are no interactions between
declarations in one file and code in another. I don't know what to do
about this -- I think that it is a problem with using files, and we
should think about what we would do if there were no files -- just
large environments full of objects. Then maybe a solution for the
giant world theory could be patched into the file theory in some way.
For hysterical porpoises, maybe I should explain why I ever came up
with this in the first place: I was trying to find a convenient way to
turn internal definitions into "auxiliary variables" so as to
eliminate extra environment frames. So, for example
(define (foo x y z)
(define (bar a b) ...)
(define (baz c) ...)
...)
would normally be thought of as meaning
(define (foo x y z)
(letrec ((bar (lambda (a b) ...))
(baz (lambda (c) ...)))
...))
but I wanted to transform this into
(define (foo x y z &auxiliary bar baz)
(set! bar (lambda (a b) ...))
(set! baz (lambda (c) ...))
...)
where the non-existent "&auxiliary" syntax just means that when foo is
called it creates a frame with extra unassigned variables of the given
name. This mechanism is a very efficient way to do internal
definitions, and reduces the amount of consing, lookup time, etc.
I decided that if I treated the body of a procedure as an "open
LETREC", where the definitions were thought of as an extension to the
evaluation environment, then conversion between these two forms would
be very easy.
Mumble. Sorry about the confusion -- especially since it wasn't very
relevant to the original discussion.
∂12-Apr-86 0101 @MC.LCS.MIT.EDU:rkirchne%carleton.csnet@CSNET-RELAY.ARPA The generality of define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 12 Apr 86 01:01:26 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 12 Apr 86 03:42:00 EST
Received: from carleton by csnet-relay.csnet id aa05699; 12 Apr 86 3:36 EST
Date: Thu, 10 Apr 86 14:18 CST
From: Kirchner@CSNET-RELAY.ARPA,
Roger <rkirchne%carleton.csnet@CSNET-RELAY.ARPA>
To: scheme@mc.lcs.mit.edu
cc: rkirchne%carleton.csnet@CSNET-RELAY.ARPA
Subject: The generality of define
One of my students has discovered that the template syntax for
defining procedures is quite general, a fact which might be
obvious, but should be pointed out.
Although I knew that
(define (square x) (* x x))
is equivalent to
(define square (lambda (x) (* x x))),
I did not realize that something like
(define ((linear a b) x) (+ a (* b x)))
is possible and is equivalent to
(define (linear a b) (lambda (x) (+ (* b x)))).
Roger Kirchner, Carleton College
∂12-Apr-86 0810 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU The generality of define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 12 Apr 86 08:09:58 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 12 APR 86 10:03:43 EST
Date: 12 Apr 1986 10:03 EST (Sat)
Message-ID: <JINX.12198249065.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: Kirchner@CSNET-RELAY.ARPA,
Roger <rkirchne%carleton.csnet@CSNET-RELAY.ARPA>
Cc: scheme@MC.LCS.MIT.EDU
Subject: The generality of define
In-reply-to: Msg of 10 Apr 1986 15:18-EST from Kirchner at CSNET-RELAY.ARPA,
Roger <rkirchne%carleton.csnet at CSNET-RELAY.ARPA>
MIT Scheme has recognized the
(define ((linear a b) x) (+ a (* b x)))
syntax for a few years. It was suggested by a student as an extension
to the usual
(define (square x) (* x x))
syntax. The (obvious) reason being that in the same way that
(square 5) evaluates to the value of (* 5 5)
((linear 2 3) 4) evaluates to the value of (+ 2 (* 3 4))
∂12-Apr-86 0830 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@mc.lcs.mit.edu early binding (150 lines)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 12 Apr 86 08:30:12 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 12 Apr 86 10:27:42 EST
Received: from mc.lcs.mit.edu by CSNET-RELAY.ARPA id a008600;
12 Apr 86 10:24 EST
Date: 12 Apr 1986 10:25 EST (Sat)
Message-ID: <JINX.12198253090.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@xx.lcs.mit.edu>
To: CPH%OZ.AI.MIT.EDU@xx.lcs.mit.edu
Cc: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>,
RRRS-Authors%mit-mc@CSNET-RELAY.ARPA
Subject: early binding (150 lines)
In-reply-to: Msg of 11 Apr 1986 21:21-EST from CPH%OZ.AI.MIT.EDU at xx.lcs.mit.edu
Actually, I don't have any real objection to declarations working when
typed in -- it is just the case that they currently do not in MIT
Scheme. The model for declarations that I described in my earlier
message does not fit the "top level interaction" view very well, since
it is essentially a static model. But, appropriate or not, I think
that it would work fine if interactive declarations were implemented.
While I can't give a rational answer, my intuition tells me that they
would be very confusing. I know that in their presence the system
would lose some of the debuggability that it currently has and that I
consider crucial. While I'm debugging a piece of code I usually don't
care that much about its speed but I want as few constraints as
possible to redo anything I want. These top level declarations would
get in my way. Once the code is debugged I can sacrifice some
debuggability for speed, which is what I use declarations for, but
then it is reasonable to "compile" the code with a "compiler" that
understands and uses the declarations.
Actually, like keyboard inputs. This interface needs alot of work and
that is one of the things needed -- declarations have to be treated
specially in this case. In particular, suppose that you want to
compile a single procedure definition in a buffer that contains a top
level declaration in some other part of the buffer. It seems to me
that the editor should know about the declaration specially and use it
when compiling single procedures.
The same problem appears here. If I'm evaluating individual procedures
from editor buffers, it is probably because I am still debugging the
code, in which case I don't want any constraints that limit my
debugging possibilites. Once the code is debugged, I will probably
not be loading individual definitions, so using a "compiler" is
appropriate.
I believe that although it might be misleading to somebody doing
benchmarks (as it is and has been in the case of MIT Scheme), we have
the best of both worlds, because incremental debugging and development
are not hindered by performance constraints, yet the performance can
be obtained when desired.
∂12-Apr-86 1434 @MC.LCS.MIT.EDU:KMP@SCRC-STONY-BROOK.ARPA (DEFINE (((...) ...) ...) ...)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 12 Apr 86 14:34:07 PST
Received: from SCRC-STONY-BROOK.ARPA by MC.LCS.MIT.EDU 12 Apr 86 17:35:13 EST
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 462162; Sat 12-Apr-86 17:32:20-EST
Date: Sat, 12 Apr 86 17:32 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: (DEFINE (((...) ...) ...) ...)
To: Scheme@MIT-MC.ARPA
cc: JINX@MIT-AI.ARPA, rkirchne%carleton.csnet@CSNET-RELAY.ARPA
References: The message of 10 Apr 86 15:18-EST from rkirchne%carleton.csnet@CSNET-RELAY.ARPA,
<JINX.12198249065.BABYL@MIT-OZ>
Message-ID: <860412173221.2.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Although Jinx didn't mention it explicitly, it's worth mentioning that although
this is one possible natural interpretation of nested lists in DEFINE's name
position, there are other possible interpretations and the Scheme communities are
not in agreement about how to interpret this. As such, no matter how natural it
feels, it's worth noting that it's not -so- natural that works in every Scheme
dialect. Some dialects treat it as an error; others might assign other meanings.
Hence, even though some dialects have it and some people find it fun (myself
included, by the way), it's worth noting that it's not portable (at least, insofar
as portable is currently defined by the Revised Revised Report on Scheme).
∂12-Apr-86 1453 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@mc.lcs.mit.edu meaning of *global* define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 12 Apr 86 14:53:02 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 12 Apr 86 17:43:05 EST
Received: from tektronix by csnet-relay.csnet id a011645; 12 Apr 86 17:40 EST
Received: from csnet-relay by tektronix.tektronix.CSNET id aa17773;
12 Apr 86 13:50 PST
Received: from mc.lcs.mit.edu by CSNET-RELAY.ARPA id a008858;
12 Apr 86 10:57 EST
Date: 12 Apr 1986 10:59 EST (Sat)
Message-ID: <JINX.12198259201.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@xx.lcs.mit.edu>
To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
Cc: rrrs-authors%mit-mc%tektronix.csnet@CSNET-RELAY.ARPA
Subject: meaning of *global* define
In-reply-to: Msg of 11 Apr 1986 15:09-EST from willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
3. MIT's peculiar semantics for DEFINE is (semantically) dirty.
I disagree. Local DEFINE is just a tag for an implicit LETREC. The
syntax might be pretty or ugly (according to personal taste), but the
semantics is the same as the semantics for LETREC. Incremental DEFINE
(a very different beast, we are just overloading the syntax) is
semantically dirty, but so is LOAD, and they are both in the same
class (interactive features).
It doesn't follow that any mechanism satisfying both 1.a and 1.b must be
semantically dirty.
I agree, but I have not seen a better one. It is also not clear to me
to what degree it is dirty. I agree that a denotational semantics
incorporating incremental DEFINE becomes more complicated, but that
runs counter to the intuition found in many beginners. LETREC and
local DEFINE are much harder to explain than incremental DEFINE. If
the model becomes complicated when explaining intuitively simple
behaviour, this may just mean that the model is not adequate. As far
as I know, denotational semantics is only good for explaining the
static behaviour of programs, and incremenatal DEFINE is only used
during interaction.
What I don't understand (but would like to) is
why MIT's semantics for DEFINE is more useful for debugging than
semantically clean mechanism such as assignments and first class
environments (without side effects).
Assignments are not powerful enough. As a vague example, consider the
following: It is often the case that while debugging I find that some
procedure FOO calls BAR incorrectly. BAR changed but I forgot to
change FOO to reflect this. Very often making FOO have its own local
version of BAR which reformats the arguments allows me to continue
debugging (although I change FOO's source so that it will be right the
next time). Assignment would not help here, since I would then be
changing the value of BAR that everybody else sees.
In David Bartley's example, it seems obvious that the USER environment
should be disjoint from the SYSTEM environment in the sense that there
should be no identifier I such that USER(I) = SYSTEM(I). (This can be
accomplished without any hocus pocus like side effects to environments
or MIT semantics for DEFINE.)
We do not use incremental DEFINE for this. Again, incremental DEFINE
is ONLY an interactive feature. The way we accomplish this (in the
student system) is by having a different environment for the system
and users. The initial user environment has all the appropriate
bindings, but does not share these bindings with the system. Thus
assignment "works" as expected.
Question for the T people: Assume there are 2 locales, A and B, such
that B inherits bindings from A (I don't know whether this makes sense
in T, but I think it does). A has a binding for FOO whose value is a
procedure. B has procedure BAR closed in it, and BAR freely
references FOO. If a user then (interactively) defines (lsets ?) FOO
in locale B, does this definition shadow the one in A? Only for newly
closed procedures? Also for old ones like BAR? I have had the
impression that the behaviour of your locales was very similar to the
behaviour of all our environments, and I'm just trying to find out.
∂13-Apr-86 2255 @MC.LCS.MIT.EDU:CPH%OZ.AI.MIT.EDU@mc.lcs.mit.edu early binding (150 lines)
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 13 Apr 86 22:55:01 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 14 Apr 86 01:56:47 EST
Received: from mc.lcs.mit.edu by CSNET-RELAY.ARPA id a023352; 14 Apr 86 1:50 EST
Date: Mon, 14 Apr 1986 01:51 EST
Message-ID: <CPH.12198683795.BABYL@MIT-OZ>
From: CPH%OZ.AI.MIT.EDU@xx.lcs.mit.edu
To: Bill Rozas <JINX%OZ.AI.MIT.EDU@xx.lcs.mit.edu>
Cc: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>,
CPH%OZ.AI.MIT.EDU@xx.lcs.mit.edu, RRRS-Authors%mit-mc@CSNET-RELAY.ARPA
Subject: early binding (150 lines)
In-reply-to: Msg of 12 Apr 1986 10:25-EST from Bill Rozas <JINX%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
Date: Saturday, 12 April 1986 10:25-EST
From: Bill Rozas <JINX%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU>
Actually, I don't have any real objection to declarations working when
typed in -- it is just the case that they currently do not in MIT
Scheme.
While I can't give a rational answer, my intuition tells me that they
would be very confusing.
Actually, like keyboard inputs. This interface needs alot of work and
that is one of the things needed -- declarations have to be treated
specially in this case. In particular, suppose that you want to
compile a single procedure definition in a buffer that contains a top
level declaration in some other part of the buffer. It seems to me
that the editor should know about the declaration specially and use it
when compiling single procedures.
The same problem appears here. If I'm evaluating individual procedures
from editor buffers, it is probably because I am still debugging the
code, in which case I don't want any constraints that limit my
debugging possibilites.
Don't worry, I'm not advocating giving away the store.
I agree that it could be a problem, in both cases. On the other hand,
suppose in both cases that there were switches to turn the action of
"interactive declarations" on or off. Then, by defaulting them to
off, no one could ever get confused. However, I would probably have
some of the switches turned on, because many of the declarations that
I use would not get in my way during debugging. (In fact I normally
compile everything with USUAL-INTEGRATIONS before debugging it
anyway.)
∂14-Apr-86 0131 @MC.LCS.MIT.EDU:rkirchne%carleton.csnet@CSNET-RELAY.ARPA define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 14 Apr 86 01:31:30 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 14 Apr 86 04:32:38 EST
Received: from carleton by csnet-relay.csnet id aa24474; 14 Apr 86 4:22 EST
Date: Sun, 13 Apr 86 15:53 CST
From: Kirchner@CSNET-RELAY.ARPA,
Roger <rkirchne%carleton.csnet@CSNET-RELAY.ARPA>
To: scheme@mc.lcs.mit.edu
cc: rkirchne%carleton.csnet@CSNET-RELAY.ARPA
Subject: define
Kent M Pitman said that there are other possible interpretations of
(DEFINE (((...) ...) ...) ...)
besides as an extended template for procedure definition.
What would be the objections to making this interpretation standard?
If
(define (comp f g) (lambda (x) (f (g x))))
is allowed, why shouldn't
(define ((comp f g) x) (f (g x)))
be allowed?
Evidently it is in MIT Scheme, and it is in PC Scheme, an
implementation of TI Scheme. In what Schemes is it allowed,
which treat it as an error, and which give it a different
interpretation?
Roger Kirchner
∂14-Apr-86 1337 JAR@MC.LCS.MIT.EDU define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 14 Apr 86 13:33:05 PST
Date: Mon, 14 Apr 86 16:32:51 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: define
To: rkirchne%carleton.csnet@CSNET-RELAY.ARPA
cc: SCHEME@MC.LCS.MIT.EDU
In-reply-to: Msg of Sun 13 Apr 86 15:53 CST from Kirchner at CSNET-RELAY.ARPA,
Roger <rkirchne%carleton.csnet at CSNET-RELAY.ARPA>
Message-ID: <[MC.LCS.MIT.EDU].883898.860414.JAR>
Date: Sun, 13 Apr 86 15:53 CST
From: Kirchner at CSNET-RELAY.ARPA,
Roger <rkirchne%carleton.csnet at CSNET-RELAY.ARPA>
To: scheme at mc.lcs.mit.edu
If
(define (comp f g) (lambda (x) (f (g x))))
is allowed, why shouldn't
(define ((comp f g) x) (f (g x)))
be allowed?
Evidently it is in MIT Scheme, and it is in PC Scheme, an
implementation of TI Scheme. In what Schemes is it allowed,
which treat it as an error, and which give it a different
interpretation?
This feature is documented by the Revised Revised Report on Scheme, as a
non-essential feature, which means that if any scheme implementation
allows this syntax, it's supposed to do what's described. Most of the
Scheme implementations out there now follow this report. Although I
don't think everyone's happy with the feature, I haven't heard of any
movement afoot to retract it in future versions of the report.
Jonathan
∂14-Apr-86 1526 JAR@MC.LCS.MIT.EDU meaning of *global* define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 14 Apr 86 15:26:37 PST
Date: Mon, 14 Apr 86 18:27:43 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: meaning of *global* define
To: JINX@MC.LCS.MIT.EDU
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU,
willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
In-reply-to: Msg of 12 Apr 1986 10:59 EST (Sat) from Bill Rozas <JINX%OZ.AI.MIT.EDU at xx.lcs.mit.edu>
Message-ID: <[MC.LCS.MIT.EDU].883974.860414.JAR>
Date: 12 Apr 1986 10:59 EST (Sat)
From: Bill Rozas <JINX%OZ.AI.MIT.EDU at xx.lcs.mit.edu>
Question for the T people: Assume there are 2 locales, A and B, such
that B inherits bindings from A (I don't know whether this makes sense
in T, but I think it does). A has a binding for FOO whose value is a
procedure. B has procedure BAR closed in it, and BAR freely
references FOO. If a user then (interactively) defines (lsets ?) FOO
in locale B, does this definition shadow the one in A?
It's supposed to. The implementation was buggy for a long time (with no
very grave consequences), although I'm under the impression that it has
been fixed.
Only for newly closed procedures?
No, for the old ones as well.
Also for old ones like BAR? I have had the
impression that the behaviour of your locales was very similar to the
behaviour of all our environments, and I'm just trying to find out.
Locales were intended to be pretty much the same as MIT Scheme
environments. (LOCALE X ... X) means the same thing as
(MAKE-ENVIRONMENT ...). You can get internal definitions in T by doing
(LAMBDA (var ...) (LOCALE definition ... body ...)).
The main difference is that not all environments are locales. DEFINE's
create bindings in the innermost locale, and lambda contours are not
locales. But this difference is apparent only if (a) you use define's
at places other than top level = the body of a LOCALE expression [a
practice I'm trying to discourage, since the meaning is in direct
conflict with Scheme] or (b) you're in the inspector looking at a
procedure and you give the B (breakpoint) command and then you type a
(define ...) form [actually a special case of (a)].
Jonathan
∂14-Apr-86 1534 JAR@MC.LCS.MIT.EDU early binding
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 14 Apr 86 15:33:53 PST
Date: Mon, 14 Apr 86 18:34:53 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: early binding
To: Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
cc: CPH@MC.LCS.MIT.EDU, RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Fri 11 Apr 86 18:44:19-CST from David Bartley <Bartley%ti-csl.csnet at CSNET-RELAY.ARPA>
Message-ID: <[MC.LCS.MIT.EDU].883993.860414.JAR>
Date: Fri 11 Apr 86 18:44:19-CST
From: David Bartley <Bartley%ti-csl.csnet at CSNET-RELAY.ARPA>
...
I'm very uneasy at the idea that a file has much of the status of a
single expression, like LETREC, particularly if I can't formulate what
it means any better than this (can you?). Perhaps it is workable,
though. I'd like to know what others think and what their experience
has been.
For the record, CLSCH (common lisp scheme) compiles both LAMBDA bodies
and file top level using the same definition scanner. The scanner is a
pre-pass which grovels over a list of expressions and definitions
(definitions aren't expressions), turning the define's into set!'s and
accumulating a list of the defined variables. For LAMBDA bodies, the
list of bound variables is simply used to create a (LET ((X
(UNASSIGNED)) (Y (UNASSIGNED)) ...) ...). For file bodies, the compiler
notes that the definitions are taking place, in order to avoid doing
invalid procedure integrations. It also puts the list of defined
variables in a call to an internal function which makes sure that at
*load* time the variables are declared not-integrable. Parts of this
are pretty kludgey (like most of CLSCH) but I liked the fact that there
was only one DEFINE scanner.
As for a better formulation of file semantics: CLSCH takes a file
(FILE F1 F2 F3 ... Fn)
to mean the same thing as the sequence of two expressions
(BIND V1 V2 ... Vm) (BEGIN F1' F2' F3' ... Fn')
where Fi' is equal to Fi, if Fi is an expression,
Fi' is equal to (SET! Vj Ej), if Fi = (DEFINE Vj Ej), and
Vj is the variable occurring in the j'th DEFINE.
BIND (not its real name) is a "subprimitive" which causes variables to
become bound at top level (or whatever the interesting level happens to
be), and (supposedly) checks to make sure that declarations are
consistent with runtime - although I'd probably say that's actually a
job for SET!, which should go uncompile and recompile (or mark as
invalid, or whatever) any code in the system (or world) whose compilation
becomes invalid as a result of the assignment. (I don't know how well
this would work. I'd like to try it.)
∂14-Apr-86 1549 @MC.LCS.MIT.EDU:JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU meaning of *global* define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 14 Apr 86 15:49:11 PST
Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 14 APR 86 18:48:23 EST
Date: 14 Apr 1986 17:48 EST (Mon)
Message-ID: <JINX.12198858017.BABYL@MIT-OZ>
From: Bill Rozas <JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU>
To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
Cc: JINX%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU, rrrs-authors@MC.LCS.MIT.EDU
Subject: meaning of *global* define
In-reply-to: Msg of 14 Apr 1986 14:17-EST from willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA
This is what I don't understand: Since you have to change the source
for FOO anyway, why don't you just evaluate
(SET! FOO <changed-source-for-FOO>) in the appropriate environment?
Then you would be testing your permanent code, not code that you hope
is equivalent to your permanent code. In cases where you don't want
to change the source for FOO, why don't you just evaluate
(LET ((BAR <rearranging-definition-for-BAR>))
(SET! FOO <original-source-for-FOO>))
in the appropriate environment?
What if FOO has already generated lots of procedures which are all
over the place and the actual use of BAR is within them?
∂14-Apr-86 1625 @MC.LCS.MIT.EDU,@XX.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: meaning of *global* define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 14 Apr 86 16:24:39 PST
Received: from XX.LCS.MIT.EDU by MC.LCS.MIT.EDU 14 Apr 86 19:18:25 EST
Received: from CSNET-RELAY.ARPA by XX.LCS.MIT.EDU with TCP; Mon 14 Apr 86 19:22:13-EST
Received: from tektronix by csnet-relay.csnet id a002865; 14 Apr 86 18:42 EST
Received: by tektronix.TEK (5.31/6.05)
id AA14156; Mon, 14 Apr 86 12:39:46 PST
Received: by tekchips (5.31/5.14)
id AA06708; Mon, 14 Apr 86 12:40:07 PST
Message-Id: <8604142040.AA06708@tekchips>
To: RRRS-Authors%mit-mc@xx.lcs.mit.edu
Subject: Re: meaning of *global* define
In-Reply-To: Your message of 12 Apr 1986 10:59 EST (Sat).
<JINX.12198259201.BABYL@MIT-OZ>
Date: 14 Apr 86 12:40:05 PST (Mon)
From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
What I don't understand (but would like to) is
why MIT's semantics for DEFINE is more useful for debugging than
semantically clean mechanism such as assignments and first class
environments (without side effects).
Assignments are not powerful enough. As a vague example, consider the
following: It is often the case that while debugging I find that some
procedure FOO calls BAR incorrectly. BAR changed but I forgot to
change FOO to reflect this. Very often making FOO have its own local
version of BAR which reformats the arguments allows me to continue
debugging (although I change FOO's source so that it will be right the
next time). Assignment would not help here, since I would then be
changing the value of BAR that everybody else sees.
This is what I don't understand: Since you have to change the source
for FOO anyway, why don't you just evaluate
(SET! FOO <changed-source-for-FOO>) in the appropriate environment?
Then you would be testing your permanent code, not code that you hope
is equivalent to your permanent code. In cases where you don't want
to change the source for FOO, why don't you just evaluate
(LET ((BAR <rearranging-definition-for-BAR>))
(SET! FOO <original-source-for-FOO>))
in the appropriate environment?
This is important to me because if the main reason for MIT's semantics
for DEFINE is to avoid compilation time, then extremely fast compilers
look like a better solution to the problem.
Peace, Will
∂15-Apr-86 1514 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: early binding
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 15 Apr 86 15:14:07 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 15 Apr 86 18:15:07 EST
Received: from ti-csl by csnet-relay.csnet id ac14655; 15 Apr 86 17:35 EST
Received: by tilde id AA02000; Tue, 15 Apr 86 13:35:52 cst
Date: Tue 15 Apr 86 13:17:22-CST
From: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Re: early binding
To: JAR%MC.LCS.MIT.EDU@CSNET-RELAY.ARPA
Cc: CPH%MC.LCS.MIT.EDU@CSNET-RELAY.ARPA,
RRRS-AUTHORS%MC.LCS.MIT.EDU@CSNET-RELAY.ARPA,
Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
In-Reply-To: <[MC.LCS.MIT.EDU].883993.860414.JAR>
Message-Id: <12199081731.72.BARTLEY@CSC60>
>Date: Mon, 14 Apr 86 18:34:53 EST
>From: Jonathan A Rees <JAR%MC.LCS.MIT.EDU@csnet-relay>
>
> Date: Fri 11 Apr 86 18:44:19-CST
> From: David Bartley <Bartley%ti-csl.csnet at CSNET-RELAY.ARPA>
>
> ...
> I'm very uneasy at the idea that a file has much of the status of a
> single expression, like LETREC, particularly if I can't formulate what
> it means any better than this (can you?). Perhaps it is workable,
> though. I'd like to know what others think and what their experience
> has been.
>
>For the record, CLSCH (common lisp scheme) compiles both LAMBDA bodies
>and file top level using the same definition scanner. The scanner is a
>pre-pass which grovels over a list of expressions and definitions
>(definitions aren't expressions), turning the define's into set!'s and
>accumulating a list of the defined variables. [...]
>
>As for a better formulation of file semantics: CLSCH takes a file
> (FILE F1 F2 F3 ... Fn)
>to mean the same thing as the sequence of two expressions
> (BIND V1 V2 ... Vm) (BEGIN F1' F2' F3' ... Fn')
>where Fi' is equal to Fi, if Fi is an expression,
> Fi' is equal to (SET! Vj Ej), if Fi = (DEFINE Vj Ej), and
> Vj is the variable occurring in the j'th DEFINE.
(1) What do you do if Fi is a BEGIN? For example, in
(FILE F1 F2 ... (BEGIN (DEFINE A ...)(FOO)(DEFINE B ...)) ... Fn),
are the DEFINEs for both A and B collected into a BIND by your pre-pass?
(2) Do you expand macros during the pre-pass? What if a macro expands
into a DEFINE or a BEGIN containing a DEFINE?
(3) How large a file can you handle comfortably with this approach?
An implementation for a small machine may choke when trying to read
all of the forms in a file at one time. They also are less likely to
have fast disk access, so reading the file twice could also be a
disadvantage (particularly if macros get expanded twice).
Regards,
David Bartley
-------
∂15-Apr-86 1624 @MC.LCS.MIT.EDU,@XX.LCS.MIT.EDU:willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Re: meaning of *global* define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 15 Apr 86 16:24:33 PST
Received: from XX.LCS.MIT.EDU by MC.LCS.MIT.EDU 15 Apr 86 18:54:56 EST
Received: from CSNET-RELAY.ARPA by XX.LCS.MIT.EDU with TCP; Tue 15 Apr 86 18:54:44-EST
Received: from tektronix by csnet-relay.csnet id ae15138; 15 Apr 86 18:41 EST
Received: by tektronix (5.31/5.14)
id AA18175; Tue, 15 Apr 86 12:49:21 PST
Received: by tekchips (5.31/5.14)
id AA19865; Tue, 15 Apr 86 12:49:39 PST
Message-Id: <8604152049.AA19865@tekchips>
To: JINX%OZ.AI.MIT.EDU@xx.lcs.mit.edu
Cc: RRRS-Authors%mit-mc@xx.lcs.mit.edu
Subject: Re: meaning of *global* define
In-Reply-To: Your message of 14 Apr 1986 17:48 EST (Mon).
<JINX.12198858017.BABYL@MIT-OZ>
Date: 15 Apr 86 12:49:36 PST (Tue)
From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA
What if FOO has already generated lots of procedures which are all
over the place and the actual use of BAR is within them?
Thanks. I had thought of this, but it seemed less significant than
compile time. Do people feel that the above situation is the main
reason why DEFINE should side effect an environment?
What is the difference between having incorrect procedures all over
the place and having incorrect numbers, lists, strings, or vectors all
over the place? If I interactively say
(define x 3)
(define env (make-environment (define (foo) (vector x x))))
(define vec (eval '(foo) env))
and then realize that I made a mistake so I say
(eval '(define x 4) env)
why shouldn't vec become #(4 4)?
Peace, Will
∂16-Apr-86 1808 JAR@MC.LCS.MIT.EDU early binding
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 16 Apr 86 17:56:24 PST
Date: Wed, 16 Apr 86 20:57:31 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: early binding
To: Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Tue 15 Apr 86 13:17:22-CST from David Bartley <Bartley%ti-csl.csnet at CSNET-RELAY.ARPA>
Message-ID: <[MC.LCS.MIT.EDU].886327.860416.JAR>
Date: Tue 15 Apr 86 13:17:22-CST
From: David Bartley <Bartley%ti-csl.csnet at CSNET-RELAY.ARPA>
(1) What do you do if Fi is a BEGIN? For example, in
(FILE F1 F2 ... (BEGIN (DEFINE A ...)(FOO)(DEFINE B ...)) ... Fn),
are the DEFINEs for both A and B collected into a BIND by your pre-pass?
Yes -- this is an extra bonus feature.
(2) Do you expand macros during the pre-pass? What if a macro expands
into a DEFINE or a BEGIN containing a DEFINE?
Yes, macros get expanded in the pre-pass, so it "works" for a macro to
expand into (begin (define ...) ...). Only the top level forms get
macro expanded, not their subforms (lazy macroexpansion).
(3) How large a file can you handle comfortably with this approach?
I haven't tried anything big, and I've only run CLSCH on a 3600 anyhow,
so I assume it could handle files of several magabytes, if anyone was
crazy enough to create one.
An implementation for a small machine may choke when trying to read
all of the forms in a file at one time.
An implementation of Common Lisp is going to choke a small machine to
death anyhow.
They also are less likely to
have fast disk access, so reading the file twice could also be a
disadvantage (particularly if macros get expanded twice).
Agreed. This approach probably wouldn't be so good on a small machine.
But let's try a thought experiment: I would consider a 100Kbyte source
file to be very big. (CLSCH itself is 70K and ought to be split into a
couple of files, except that that would make distribution more
difficult.) Suppose that it doubles in size when converted to
s-expression, and gets another 25% bigger when top-level macros are
expanded. Suppose also that a copying collector is used. Then we're
talking on the order of a half a meg of temporary storage required.
That doesn't sound unreasonable to me, given that the source file was
exceptionally large anyhow; I might not say this if I was trying to use
a PC, but I doubt I'd try coping with files that big on a PC in any
case.
Given the limitations you're talking about, I guess I'd just try to
suffer with forward references not reaching very far. This doesn't seem
much worse to me than the fact that forward references won't work easily
across files either. Declarations of the form "don't integrate CAR" or
"definition of CAR will be found in file X" are needed in any case and
can serve both to make independent compilation work and to make one-pass
compilation work, if that's what you want. In any case, the user should
by all means be notified if inconsistencies between truth & assumptions
arise.
Jonathan.
∂17-Apr-86 0909 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: early binding
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 17 Apr 86 09:09:43 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 17 Apr 86 12:10:51 EST
Received: from ti-csl by csnet-relay.csnet id ab06099; 17 Apr 86 12:03 EST
Received: by tilde id AA00173; Thu, 17 Apr 86 10:55:13 cst
Date: Thu 17 Apr 86 10:52:41-CST
From: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Re: early binding
To: JAR%mc.lcs.mit.edu@CSNET-RELAY.ARPA
Cc: RRRS-AUTHORS%mc.lcs.mit.edu@CSNET-RELAY.ARPA,
Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
In-Reply-To: <[MC.LCS.MIT.EDU].886327.860416.JMessage-ID: <12199579682.13.BARTLEY@CSC60>
You've pretty well answered my questions, thanks... I have one last
(small) question and comment on the following:
>Date: Wed, 16 Apr 86 20:57:31 EST
>From: Jonathan A Rees <JAR%mc.lcs.mit.edu@CSNET-RELAY.ARPA>
>
> Date: Tue 15 Apr 86 13:17:22-CST
> From: David Bartley <Bartley%ti-csl.csnet at CSNET-RELAY.ARPA>
>
> (1) What do you do if Fi is a BEGIN? For example, in
>
> (FILE F1 F2 ... (BEGIN (DEFINE A ...)(FOO)(DEFINE B ...)) ... Fn),
>
> are the DEFINEs for both A and B collected into a BIND by your pre-pass?
>
>Yes -- this is an extra bonus feature.
>
> (2) Do you expand macros during the pre-pass? What if a macro expands
> into a DEFINE or a BEGIN containing a DEFINE?
>
>Yes, macros get expanded in the pre-pass, so it "works" for a macro to
>expand into (begin (define ...) ...). Only the top level forms get
>macro expanded, not their subforms (lazy macroexpansion).
If only the top level forms get macro expanded, then a DEFINE at the
top level of a macro called FOO would not be recognized in the top
level form (BEGIN (FOO A)(FOO B)), right? That is, if (FOO A)
macro-expands into (DEFINE A 42), we'd have (BEGIN (DEFINE A
42)(DEFINE B 42)), but you'd not catch these particular ``top level''
defines?
Similarly, suppose (BAR X Y Z) were a macro that expanded into
(BEGIN X Y Z). What would happen to (BAR (FOO A)(FOO B))? Would it
be fully expanded into (BEGIN (DEFINE A 42)(DEFINE B 42)) in order
to catch the definitions?
The same question applies to macro expanding the bodies of lambdas in
order to detect ``top level'' DEFINEs to be collected into a LETREC.
To be honest, I'm not sure how deep my own PC Scheme goes in macro
expansion to detect such definitions.
Regards,
David Bartley
-------
∂17-Apr-86 1241 JAR@MC.LCS.MIT.EDU early binding
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 17 Apr 86 12:40:59 PST
Date: Thu, 17 Apr 86 15:26:16 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: early binding
To: Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Thu 17 Apr 86 10:52:41-CST from David Bartley <Bartley%ti-csl.csnet at CSNET-RELAY.ARPA>
Message-ID: <[MC.LCS.MIT.EDU].887368.860417.JAR>
Date: Thu 17 Apr 86 10:52:41-CST
From: David Bartley <Bartley%ti-csl.csnet at CSNET-RELAY.ARPA>
If only the top level forms get macro expanded, then a DEFINE at the
top level of a macro called FOO would not be recognized in the top
level form (BEGIN (FOO A)(FOO B)), right? That is, if (FOO A)
macro-expands into (DEFINE A 42), we'd have (BEGIN (DEFINE A
42)(DEFINE B 42)), but you'd not catch these particular ``top level''
defines?
Similarly, suppose (BAR X Y Z) were a macro that expanded into
(BEGIN X Y Z). What would happen to (BAR (FOO A)(FOO B))? Would it
be fully expanded into (BEGIN (DEFINE A 42)(DEFINE B 42)) in order
to catch the definitions?
The same question applies to macro expanding the bodies of lambdas in
order to detect ``top level'' DEFINEs to be collected into a LETREC.
To be honest, I'm not sure how deep my own PC Scheme goes in macro
expansion to detect such definitions.
Sorry I wasn't clear. All of these define's are found by CLSCH. Bodies
of begins are considered to be top level if the begin is at top level.
But only enough macro expansion is done to be able to find all possible
defines and begins.
Since exactly the same scanner is used for lambda-expressions, the same
answers apply.
Jonathan
∂23-Apr-86 1609 andy@aids-unix(AndyCromarty)@MC.LCS.MIT.EDU Re: The generality of define
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 23 Apr 86 16:09:18 PST
Date: Wed, 23 Apr 86 19:09:53 EST
From: andy@aids-unix (Andy Cromarty)
Sender: JAR@MC.LCS.MIT.EDU
Subject: Re: The generality of define
To: SCHEME@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].893069.860423.JAR>
Date: 21 Apr 1986 09:43-PST
From: andy@aids-unix (Andy Cromarty)
Cc: rkirchne%carleton.csnet@CSNET-RELAY
Subject: Re: The generality of define
"Although I knew that
(define (square x) (* x x))
is equivalent to
(define square (lambda (x) (* x x))), ...."
Actually, a properly implemented
(define (square x) (* x x))
is not equivalent to
(define square (lambda (x) (* x x)))
at all, but rather to
(define square (rec square (lambda (x) (* x x))))
The distinction between the rec and lambda forms is important during
definition of self-recursive procedures, as is noted (albeit somewhat
tersely) in the RRRS. For example, consider
(define (fact1 n)
(if (<? n 2)
1
(* n (fact1 (-1+ n)))))
(define copy1 fact1)
(define fact2
(lambda (n)
(if (<? n 2)
1
(* n (fact2 (-1+ n))))))
(define copy2 fact2)
Both fact1 and fact2 are definitions of factorial, and under
most circumstances there will be no difference between them.
If we subsequently redefine fact1 and fact2, however:
(define fact1 (lambda (x) x)) ; For new fact1, just echo x back.
(define fact2 (lambda (x) x)) ; Same thing for the new fact2.
then we get different results from copy1 and copy2:
(copy1 5) => 120 ; i.e. 5!
(copy2 5) => 20 ; i.e. same as "(* 5 ((lambda (x) x) 4))"
Since the implicit REC in the (fact1 n) definition in essence creates a
pointer to the fact1 procedure at the time of creation, the semantics
of that procedure becomes immune to subsequent changes in its own name.
In the case of fact2, the name wasn't "protected" by a REC, so copy2
calls the new fact2 procedure after fact2 has been redefined, rather
than the original fact2. Obviously, both the REC and LAMBDA forms of
define can be useful, depending on the programmer's needs.
asc
∂23-Apr-86 2013 JAR@MC.LCS.MIT.EDU variata
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 23 Apr 86 20:12:54 PST
Date: Wed, 23 Apr 86 23:13:58 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: variata
To: RRRS-AUTHORS@MC.LCS.MIT.EDU
Message-ID: <[MC.LCS.MIT.EDU].893236.860423.JAR>
Anyone who wants to receive a copy of the "Revised↑3 Report on the
Algorithmic Language Scheme" should make sure that I have his or her US
mail address. I'll also make the LaTeX sources available via Internet
FTP. I'm aiming to get it to SIGPLAN by May 1 so it can be in the July
issue, but somehow I have managed to misplace a week or two (illness &
general procrastination) so there is beginning to be a shadow of a doubt
on this proposition, since this gives practically no time for me to get
everyone's comments on the draft. I'll mail out a draft as soon as I
can (but not immediately) and we'll see what happens.
It's in two-column format and is currently about 38 pages long (only a
little more than twice the size of the Algol 60 report!), including
index, formal semantics, and formal syntax (each of which is 2 pages).
Here are a few more little editorial decisions. Please let me know
if you have serious objections. I don't believe any of the ones not
previously discussed should matter much to anyone in any practical
sense, and nearly all of them serve to shorten and simplify the report.
- Rest-argument lists are always freshly consed (semantically speaking).
[All h*** breaks loose if not.]
- An ELSE clause must be last in a COND or CASE. [If implementations
want to allow it elsewhere that's fine, but why should arbitrary
position be essential?]
- (ELSE) isn't a legal clause. [If it is, what does it return, and why?]
- (COND) and (CASE x) are syntactically legal expressions. [No one
objected to this liberalization when I raised the question before.]
- (BEGIN) and (LAMBDA (X)) are not necessarily syntactically legal.
[Several people objected to this extension.]
- CASE selectors must all be distinct. [This is as in Common Lisp;
it assists error checking; and it means nothing has to be said about
the order in which clauses are processed.]
- It's not specified what happens if the constants in a CASE are
objects other than numbers, symbols, characters, or booleans.
[This allows implementations to decide for themselves what
happens in other situations - EQV?, EQUAL?, etc.]
- BOOLEAN? is a new essential procedure. [For symmetry with other type
predicates. I didn't ask previously whether or not it should be
essential; I hope it's OK if it is.]
- EQ? and EQV? must both return true if their arguments are both
empty strings or both empty vectors. [I believe that this is
implicit in the RRRS. I guess making it explicit might require
implementations which don't already do so to special case
(MAKE-STRING 0) and (MAKE-VECTOR 0) -- is that OK? If not, then the
documentation for EQ? and EQV? has to have yet another special case
in it (since zero-length vectors aren't operationally distinguishable
from each other), and I'll have to add yet another implementation
rationale -- ugh. Also, if (MAKE-STRING 0) and (MAKE-VECTOR 0) are
REQUIRED to return new objects, then the formal semantics becomes
significantly hairier.]
The RRRS says nothing at all about whether the result of APPEND sharing
structure with its arguments. Common Lisp says explicitly that all
arguments but the last are copied, and the last one never is. I think
this is wrong, and maybe incompatible with existing implementations. T
permits sharing (not clobbering) whenever that makes sense, e.g.
(let ((x (list 1 2)))
(eq? x (cdr (append '(a) x '() '()))))
might be true. Is it OK if I make this explicitly OK?
What about (let ((x (list 'a))) (eq? x (reverse x))) ?
Jonathan
∂25-Apr-86 0406 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: variata
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Apr 86 04:05:53 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 25 Apr 86 07:07:02 EST
Received: from ti-csl by csnet-relay.csnet id ag08862; 24 Apr 86 11:36 EST
Received: by tilde id AA19587; Thu, 24 Apr 86 09:50:31 cst
Date: Thu 24 Apr 86 09:43:04-CST
From: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Re: variata
To: JAR%mc.lcs.mit.edu@CSNET-RELAY.ARPA,
RRRS-AUTHORS%mc.lcs.mit.edu@CSNET-RELAY.ARPA
Cc: Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
In-Reply-To: <[MC.LCS.MIT.EDU].893236.860423.JAR>
Message-Id: <12201402017.13.BARTLEY@CSC60>
>Date: Wed, 23 Apr 86 23:13:58 EST
>From: Jonathan A Rees <JAR%mc.lcs.mit.edu@CSNET-RELAY.ARPA>
>Subject: variata
I'm in general agreement with JAR's proposals, but...
> - (ELSE) isn't a legal clause. [If it is, what does it return, and why?]
> - (COND) and (CASE x) are syntactically legal expressions. [No one
> objected to this liberalization when I raised the question before.]
What is the difference between (COND (ELSE)) and (COND)? Why is one
wrong but the other OK?
> - (BEGIN) and (LAMBDA (X)) are not necessarily syntactically legal.
> [Several people objected to this extension.]
What is the difference between (BEGIN) and (COND)? Why is one wrong
but the other OK?
> - It's not specified what happens if the constants in a CASE are
> objects other than numbers, symbols, characters, or booleans.
> [This allows implementations to decide for themselves what
> happens in other situations - EQV?, EQUAL?, etc.]
I think CASE should continue to be defined in terms of EQV?. This is
consistent with Common LISP's CASE, which is defined in terms of EQL.
There's also the issue of program-generated programs, which could
conceivably have weird CASE keys (like closure objects) that are known
to be EQ? or EQV? to other constants in the same procedure. It's
bizarre, but I'd like to know what to expect.
> - EQ? and EQV? must both return true if their arguments are both
> empty strings or both empty vectors. [...]
What about those of us contemplating extending Scheme to include other
compound types? What happens with the following?
(EQ? (MAKE-VECTOR 0) (MAKE-ARRAY '(0)))
(EQ? (MAKE-VECTOR 0) (MAKE-ARRAY '(0 0)))
(EQ? (MAKE-ARRAY '(0 0)) (MAKE-ARRAY '(0 0)))
and my favorite,
(EQ? (MAKE-VECTOR 0 3) (MAKE-VECTOR 0 4))
By the way, is (MAKE-VECTOR 0 <exp>) valid? Is it reasonable to issue
a warning message?
What if an implementation of Scheme extends it with adjustable arrays,
as in Common LISP?
(LET ((X (MAKE-ARRAY '(0) :ADJUSTABLE 'T)))
(EQ? X (MAKE-ARRAY '(0))))
[I'm not advocating Common LISP's messy syntax, just using it for clarity.]
Common LISP says that strings are the same as simple vectors with
elements of type STRING-CHAR. Is the empty string "" EQV? to a
non-simple vector with elements of type STRING-CHAR? These questions
are particularly pertinent for those of implementing both Scheme and
Common LISP in the same name space (or one on top of the other).
>The RRRS says nothing at all about whether the result of APPEND sharing
>structure with its arguments. Common Lisp says explicitly that all
>arguments but the last are copied, and the last one never is. I think
>this is wrong, and maybe incompatible with existing implementations. T
>permits sharing (not clobbering) whenever that makes sense, e.g.
> (let ((x (list 1 2)))
> (eq? x (cdr (append '(a) x '() '()))))
>might be true. Is it OK if I make this explicitly OK?
I'd like some discussion on this. It sounds like something a LISP
programmer could trip up on, especially those who use (APPEND X '())
to copy X. Steele's book specifically mentions that APPEND will work
that way in Common LISP, but implies that it is poor style. My
inclination is to be compatible with Common LISP in order to minimize
frustration for the poor people we're trying to win over to Scheme.
>What about (let ((x (list 'a))) (eq? x (reverse x))) ?
I feel strongly that REVERSE should always copy (unless its argument
is the empty list), since it is easier to remember that rule than that
it does so only when there's more than one element in the list.
Pragmatically, I often do something like (APPEND! (REVERSE X) Y), and
wouldn't want to side effect the original list in X if it had exactly
one element. (Note that this works correctly when X is the empty
list, so this is a pretty unusual boundary condition.)
Regards,
David Bartley
-------
∂25-Apr-86 1356 JAR@MC.LCS.MIT.EDU variata
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Apr 86 13:56:08 PST
Date: Fri, 25 Apr 86 16:31:01 EST
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject: variata
To: Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
In-reply-to: Msg of Thu 24 Apr 86 09:43:04-CST from David Bartley <Bartley%ti-csl.csnet at CSNET-RELAY.ARPA>
Message-ID: <[MC.LCS.MIT.EDU].895280.860425.JAR>
Date: Thu 24 Apr 86 09:43:04-CST
From: David Bartley <Bartley%ti-csl.csnet at CSNET-RELAY.ARPA>
>Date: Wed, 23 Apr 86 23:13:58 EST
>From: Jonathan A Rees <JAR%mc.lcs.mit.edu@CSNET-RELAY.ARPA>
>Subject: variata
I'm in general agreement with JAR's proposals, but...
> - (ELSE) isn't a legal clause. [If it is, what does it return, and why?]
> - (COND) and (CASE x) are syntactically legal expressions. [No one
> objected to this liberalization when I raised the question before.]
What is the difference between (COND (ELSE)) and (COND)? Why is one
wrong but the other OK?
(COND (ELSE)) is the same as (COND (ELSE (BEGIN))), so it's OK iff
(BEGIN) is OK. But we established that (BEGIN) isn't OK, because it's
not OK in the RRRS and several people have objected to its being OK.
(COND) is OK because because (COND (test expr)) and (COND (ELSE expr))
are both OK, and that's because I proposed that the syntax of COND be
(COND <zero or more non-ELSE clauses> <optional ELSE clause>).
I don't really care about this, but I would rather NOT want to see the
syntax of COND be (COND <one or more clauses only the last of which can
be an ELSE clause>), which is what the RRRS says, because I think that's
somewhat inelegant. An alternative, however, is to make the syntax be
(COND <one or more non-ELSE clauses> <optional ELSE clause>). I guess
that would be more compatible with IF. So I want to give you the two
choices:
(a) (COND) and (COND (ELSE foo)) are both necessarily legal (compatible
with RRRS since it's more liberal).
(b) (COND) and (COND (ELSE foo)) are both not necessarily legal
(incompatible with RRRS in a way which I wouldn't expect people
to be too bothered about).
but not the choice (status quo):
(c) (COND (ELSE foo)) is legal but (COND) isn't.
You've almost convinced me that (b) is the better choice than (a). I
really don't care as much as the volume of my words would indicate, so
advise me.
I guess no one read my BNF carefully, or this would have been discussed
earlier.
> - (BEGIN) and (LAMBDA (X)) are not necessarily syntactically legal.
> [Several people objected to this extension.]
What is the difference between (BEGIN) and (COND)? Why is one wrong
but the other OK?
(BEGIN) is not ok for reasons explained above. I suggested that (COND)
be OK because it seemed consistent with (COND (ELSE exp)) already being
legal, but I think maybe you've convinced me that neither ought to be
necessarily legal.
> - It's not specified what happens if the constants in a CASE are
> objects other than numbers, symbols, characters, or booleans.
> [This allows implementations to decide for themselves what
> happens in other situations - EQV?, EQUAL?, etc.]
I think CASE should continue to be defined in terms of EQV?. This is
consistent with Common LISP's CASE, which is defined in terms of EQL.
There's also the issue of program-generated programs, which could
conceivably have weird CASE keys (like closure objects) that are known
to be EQ? or EQV? to other constants in the same procedure. It's
bizarre, but I'd like to know what to expect.
I don't think we don't disagree here. If the keys are restricted to be
numbers, symbols, characters, or booleans, EQV? and EQUAL? will give
exactly the same result, so it doesn't matter at all which predicate the
manual decides to explain CASE in terms of; so I would leave the
description to be in terms of EQV?. But observe that if it's not
specified what happens when there are constants other than numbers,
symbols, characters, or booleans, then the fact that the description is
in terms of EQV? doesn't rule out implementations extending it to use
EQUAL?.
> - EQ? and EQV? must both return true if their arguments are both
> empty strings or both empty vectors. [...]
What about those of us contemplating extending Scheme to include other
compound types? What happens with the following?
(EQ? (MAKE-VECTOR 0) (MAKE-ARRAY '(0)))
I would expect this to return false if either (a) the dimension of an
array can be changed dynamically or (b) VECTOR? never returns true of an
array or (c) there are procedures defined to work on arrays that aren't
defined to work on vectors. My principles are: EQV? should implement
the operationally-indistinguishable relation as closely as possible, and
EQ? should be as much like EQV? as possible given that it has to be
implementable as pointer comparison.
(EQ? (MAKE-VECTOR 0) (MAKE-ARRAY '(0 0)))
If there's a primitive like ARRAY-RANK or ARRAY-DIMENSIONS then these
are clearly distinct.
(EQ? (MAKE-ARRAY '(0 0)) (MAKE-ARRAY '(0 0)))
This probably depends on whether arrays are non-adjustable by default.
I forget whether or not they are.
and my favorite,
(EQ? (MAKE-VECTOR 0 3) (MAKE-VECTOR 0 4))
What standard primitive could distinguish these?
The RRRS explains EQ? and EQV? in terms the notion of operational
equivalence; I'm just trying to make this idea precise. I should
probably send out my proposed text in advance of the rest of the report,
since I think it manages to be simultaneously elegant, precise, and
compatible (except, apparently, with implementations which have multiple
empty strings & vectors).
If there's a way to operationally distinguish objects, they
aren't EQV?; if there isn't a way, I want the exceptions to be spelled
out plainly, with justifications. Why should (EQV? '() '()) be true,
but not (EQV? "" "") or (EQV? '#() '#()) ? What's the difference
between an empty list and an empty vector or empty string? Or do you
want to allow there to be more than one empty list?
If operational equivalence must allow for all possible extensions to
Scheme, then it is a completely meaningless concept (e.g. numerically
equal numbers could be distinguishable from each other, if numbers had
property lists - whatever that means), and I'm at a loss for any other
way to explain EQV?.
By the way, is (MAKE-VECTOR 0 <exp>) valid? Is it reasonable to issue
a warning message?
I think it's perfectly meaningful (see above), and there should be no
warning message.
What if an implementation of Scheme extends it with adjustable arrays,
as in Common LISP?
(LET ((X (MAKE-ARRAY '(0) :ADJUSTABLE 'T)))
(EQ? X (MAKE-ARRAY '(0))))
[I'm not advocating Common LISP's messy syntax, just using it for clarity.]
Seems to me that since "essential" vectors are simple (non-adjustable,
etc.), an adjustable vector is a very different beast. Empty simple
vectors can't be distinguished from each other (i.e. there's only one),
but adjustable empty vectors have local state, so they can be.
If vectors can be adjustable, shouldn't lists be too? (MAKE-LIST 0
:ADJUSTABLE T) could return an empty list whose length can be changed.
(Not a serious suggestion.)
Common LISP says that strings are the same as simple vectors with
elements of type STRING-CHAR. Is the empty string "" EQV? to a
non-simple vector with elements of type STRING-CHAR?
Not if there's a predicate which will distinguish simple vectors from
non-simple ones; and in Common Lisp there is.
These questions are particularly pertinent for those of implementing
both Scheme and Common LISP in the same name space (or one on top of
the other).
It's certainly easy enough to create unique empty strings and vectors
and make Scheme's MAKE-STRING and MAKE-VECTOR return them when
appropriate. I don't know whether it would be acceptable for a Common
Lisp implementation to do this when creating non-adjustble vectors of
length zero (don't have CLtL handy, will check later). The only other
time when these things are created out of Scheme's control is by the
reader, but -- as I've discovered by doing a Scheme in CL myself --
Scheme really wants its own reader anyhow, to deal with the number
syntax and with colon being a constituent character.
If people believe that it's important to be able to parse Scheme's read
syntax using only standard Common Lisp reader features, then by all
means we must allow (eq? '#() '#()) to be false, but we also have to
change the syntax of numbers, and make colon not be a constituent
character. But Scheme's eqv? could still deal with #() and "" as I
propose even if eq? doesn't.
It looks like I'll lose on this point, so I won't push it too hard. I'm
just resisting adding yet another clause which basically says "we did
this for compatibility with Common Lisp." Sorry to stir up the muck
again.
>The RRRS says nothing at all about whether the result of APPEND sharing
>structure with its arguments. Common Lisp says explicitly that all
>arguments but the last are copied, and the last one never is. I think
>this is wrong, and maybe incompatible with existing implementations. T
>permits sharing (not clobbering) whenever that makes sense, e.g.
> (let ((x (list 1 2)))
> (eq? x (cdr (append '(a) x '() '()))))
>might be true. Is it OK if I make this explicitly OK?
I'd like some discussion on this. It sounds like something a LISP
programmer could trip up on, especially those who use (APPEND X '())
to copy X. Steele's book specifically mentions that APPEND will work
that way in Common LISP, but implies that it is poor style. My
inclination is to be compatible with Common LISP in order to minimize
frustration for the poor people we're trying to win over to Scheme.
If this is what other people want I'm happy with it too (except again
for the fact that I'll have to insert another apology and another
reference to Common Lisp).
>What about (let ((x (list 'a))) (eq? x (reverse x))) ?
I feel strongly that REVERSE should always copy (unless its argument
is the empty list), since it is easier to remember that rule than that
it does so only when there's more than one element in the list.
Pragmatically, I often do something like (APPEND! (REVERSE X) Y), and
wouldn't want to side effect the original list in X if it had exactly
one element. (Note that this works correctly when X is the empty
list, so this is a pretty unusual boundary condition.)
I agree. (Except note that it doesn't copy empty lists....)
Jonathan
∂25-Apr-86 1537 @MC.LCS.MIT.EDU:andy@aids-unix Re: variata
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Apr 86 15:37:04 PST
Received: from ads-grape.ARPA by MC.LCS.MIT.EDU 25 Apr 86 18:38:08 EST
Date: Fri, 25 Apr 86 15:36:27 pst
From: andy@aids-unix (Andy Cromarty)
To: Bartley%ti-csl.csnet@CSNET-RELAY.ARPA, JAR@MC.LCS.MIT.EDU
Subject: Re: variata
Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU
The difficulty with expressions like (COND) and (BEGIN) is not
that it is difficult to define a semantics for them, but rather
that it is difficult to *intuit* a semantics for them. We can
generate any of several arcane rules to cover such special cases.
It would be much nicer if no special rules were necessary, and if
instead we could apply some very small number of general principles
in figuring out what such aberrant constructs mean when we run across
them.
At the very least, if they must be included, perhaps we could come
up with one rule, uniformly applied, to define their semantics --
preferably one consistent with (what most Scheme programmers would
take to be) the "reasonable principles" of Scheme programming.
(An informal example of such a rule -- not that I necessarily endorse
it -- would be, "Any special-form control construct (LET, COND, LAMBDA,
CASE, IF, BEGIN, LETREC, DO, etc.) that normally contains combinations-to-
evaluate in its main body may contain a null body, in which case its return
value is undefined.")
If the principal argument in favor of such vacuous constructs is that
some programs might generate them automatically -- and that strikes me
as a prima facie legitimate concern -- then we should consider what is
involved in making such programs generate only "intuitive" code instead.
Quite frankly, this doesn't seem to me to be a case where the author of
a program-writing program would be significantly constrained if uses of
BEGIN and COND are restricted to non-vacuous applications. There are lots
of cases that are much worse about which no one has yet expressed concern,
such as the RRRS permitting special forms to be "syntax" objects instead
of making them shadowable first-class bindings.
asc
∂25-Apr-86 1804 @MC.LCS.MIT.EDU:Bartley%ti-csl.csnet@CSNET-RELAY.ARPA Re: variata
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 25 Apr 86 18:04:10 PST
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 25 Apr 86 21:03:28 EST
Received: from ti-csl by csnet-relay.csnet id a007721; 25 Apr 86 19:49 EST
Received: by tilde id AA06418; Fri, 25 Apr 86 18:10:57 cst
Date: Fri 25 Apr 86 18:04:04-CST
From: David Bartley <Bartley%ti-csl.csnet@CSNET-RELAY.ARPA>
Subject: Re: variata
To: JAR%mc.lcs.mit.edu@CSNET-RELAY.ARPA
Cc: RRRS-AUTHORS%mc.lcs.mit.edu@CSNET-RELAY.ARPA,
Bartley%ti-csl.csnet@CSNET-RELAY.ARPA
In-Reply-To: <[MC.LCS.MIT.EDU].895280.860425.JAR>
Me-Id: <12201755365.13.BARTLEY@CSC60>
My thanks to Jonathan for his comprehensive reply to my questions
about his `variata'.
(1) I have no argument with your analysis of (COND) vs. (COND (ELSE))...
> [...] So I want to give you the two
>choices:
> (a) (COND) and (COND (ELSE foo)) are both necessarily legal (compatible
> with RRRS since it's more liberal).
> (b) (COND) and (COND (ELSE foo)) are both not necessarily legal
> (incompatible with RRRS in a way which I wouldn't expect people
> to be too bothered about).
>but not the choice (status quo):
> (c) (COND (ELSE foo)) is legal but (COND) isn't.
>You've almost convinced me that (b) is the better choice than (a). I
>really don't care as much as the volume of my words would indicate, so
>advise me.
I actually prefer choice (a)--I wasn't advocating anything like (b)
earlier, just asking for the rationale. I dislike (b) because I often
code something like (COND (ELSE ...)) when I know I'm going to fill in
the other cases later but I want to get the COND in there to remind me
(and to get the indentation for the ELSE right).
>I guess no one read my BNF carefully, or this would have been discussed
>earlier.
Guilty!
(2) I also have no argument with (BEGIN) being not-OK. But it seems
intuitive to me that if (COND) is OK with no obvious semantics, then
(BEGIN) might mean the same thing. Your explanation for (COND) is
that it's easier to specify, not that it's particularly meaningful.
Given that we agree that (COND) is OK, it seems that (BEGIN) should be
OK. Do those who object to that also object to (COND)?
I'm not inclined to make life difficult for you on such a minor point,
so do what you think best.
(3) No disagreement on using EQV? for CASE. I had thought you were
suggesting that we change the definition to use EQUAL?.
(4) I accept your rationale for (EQV? "" "") and (EQV? #() #()).
(5) If you consider (MAKE-VECTOR 0 <exp>) valid, then presumably you
consider (LAMBDA (X Y) X) to be valid also, along with other
expressions that aren't *provably* wrong but might be. If I argue
this one the debate will go on indefinitely until everyone agrees to
add more declarations to their systems, so I'll drop it! Of course, I
agree with the word "valid", I'm just discussing whether a development
environment for Scheme may issue warning messages about such things.
(6) If we say that two objects are EQV? if there is no predicate that
can distinguish them, then a requirement in RRRRRRS that two objects
are EQV? effectively prohibits an implementation from including such a
predicate as an extension. The only example that comes to mind is
trivial, so maybe this comment is too, but here it is:
(let ((x (make-vector 0 3))
(y (make-vector 0 4)))
(eqv? x y))
Since these are both empty vectors, am I *prohibited* from adding a
predicate that determines what fill character a vector was created
with? Are there any non-trivial examples of this?
(7) I agree that Scheme will need a different reader than Common LISP.
However, if a Common LISP routine calls a Scheme routine with "" as an
argument, will it be EQV? to a constant "" in the Scheme routine?
It's just one more pitfall of trying to mix languages, and not
necessarily one we can hope to solve unilaterally.
(8) I see no compelling reason to ``insert apologies and references to
Common LISP'' unless you are trying hard to give full rationales for
everything you do. In fact, I'd prefer just a simple mention in the
introduction to the effect that there are no ``gratuitous''
differences with Common LISP---that any you find were put there after
due deliberation! If that's not true, then I (for one) think it ought
to be, since we agreed on that at Brandeis.
(We can argue on RRRS-AUTHORS whether something is ``gratuitous,'' but
I see no reason to expose all that in the RRRRRRRRRRS.)
(9) And to end on a positive note:
> >What about (let ((x (list 'a))) (eq? x (reverse x))) ?
>
> I feel strongly that REVERSE should always copy (unless its argument
> is the empty list), since it is easier to remember that rule than that
> it does so only when there's more than one element in the list.
> Pragmatically, I often do something like (APPEND! (REVERSE X) Y), and
> wouldn't want to side effect the original list in X if it had exactly
> one element. (Note that this works correctly when X is the empty
> list, so this is a pretty unusual boundary condition.)
>
>I agree. (Except note that it doesn't copy empty lists....)
Of course. The ``this'' in ``Note that this works correctly when X is
the empty list, so this is a pretty unusual boundary condition''
refers to the action of APPEND!, not REVERSE.
-----
To summarize:
-- We agree that (ELSE) is a no-no and that (COND) and (COND (ELSE exp))
are valid.
-- I feel that (BEGIN) should have the same meaning as (COND), but I
won't push the point.
-- We agree on using EQV? for CASE.
-- We agree that (EQV? "" "") and (EQV? #() #()) are true, but I worry
about confusion when I mix Scheme and Common LISP programs.
-- I like warning messages for things like (MAKE-VECTOR 0 exp) more
than you do. We can probably agree to provide declarations so you
won't refuse to buy my system!
-- I'm concerned that defining certain objects to be EQV? prohibits
language extensions that might be able to distinguish them on the
basis of the context at their creation, but I haven't come up with a
non-trivial example.
-- I'm not apologetic about trying to avoid ``gratuitous''
differences with Common LISP, but I don't want to burden the
description of Scheme with constant references to it either.
-- We agree on REVERSE.
Sorry for yet another long message, but I'm finding this interchange
very useful and I hope others do too. I don't see anything of
sufficient importance to hold up the latest revision, so please don't
drop the ball on my account!
Regards,
David Bartley
-------